- 键盘的使用流程和显示器类似,仍然遵循三个步骤:
- CPU 向键盘控制器的寄存器发送指令来使用键盘;
- 通过文件视图来帮助用户统一使用各种终端设备;
- 键盘在指令完成后向 CPU 发出中断,CPU 进行中断处理。
L27 键盘
- 键盘的使用流程和显示器类似,仍然遵循三个步骤:
- CPU 向键盘控制器的寄存器发送指令来使用键盘;
- 通过文件视图来帮助用户统一使用各种终端设备;
- 键盘在指令完成后向 CPU 发出中断,CPU 进行中断处理。
键盘中断处理
首先在用户敲下键盘后,引发键盘中断,而键盘中断是在中断初始化的时候就设置好的。在键盘中断中,通过
inb $0x60,%al
从端口0x60
读扫描码(即 CPU 从键盘控制器的寄存器中读输入的数据),根据不同的扫描码在key_table
中执行不同的操作。接下来就是处理扫描码,如下图所示,对显示字符通常都用
do_self
函数进行处理,然后又进入到key_map
,将key_map
中对应于键盘输入字符的字符赋给%ebx
。在得到了”对应于键盘输入字符的字符“后,就将该字符放入缓冲中(
put_queue
),put_queue
函数如下图所示。下面这张图就是键盘中断处理的大致流程:
★键盘和显示器
将键盘和显示器的工作流程结合起来看,就对字符设备的工作情况有了一个大致的了解:
- 首先
printf
、scanf
是库函数,将库函数展开,就可以看到文件接口write
、read
,即进行系统调用; - 然后由于键盘和显示器都是字符设备,所以根据 inode 知道是哪种字符设备(键盘或显示器)后,就通过字符设备接口来选择是
tty_write
函数(显示器)还是tty_read
函数(键盘); - 如果是
tty_write
函数,就向缓冲(write_q
队列)中写入数据,然后con_write
从缓冲区中读取数据并输出到显示器上; - 如果是
tty_read
函数,则是从缓冲(read_q
队列)中读取数据,然后进行进一步的操作(回显或其他),而缓冲区read_q
队列中的数据则是在处理了键盘中断后输入到缓冲区中的。
- 首先