实验内容
当按下F12时,控制端所有字母
变成*
,再按一次则恢复,以此类推…
实验目的
- 加深对操作系统设备管理基本原理的认识,实践键盘中断、扫描码等概念
- 通过实践掌握Linux0.11对键盘终端和显示器终端的处理过程。
实验需要具备的基本知识
键盘I/O是一种典型的中断驱动事件,既然是中断就对应需要:1. 中断号 2. 中断处理函数。中断号实验手册已经通过set_trap_gate
函数告诉我们是0x21
(十进制的33) ,中断处理函数也已经告诉我们是keyboard_interrupt
函数。因此我们就搞清楚了我们需要进行修改的地方。
键盘输入与显示器显示整体流程
这里先给出一张图(来源Linux内核0.11完全注释),这张图展示了整个过程。
当用于在键盘上键入一个字符时,随即引起键盘中断,中断处理程序负责从键盘控制器读取对应的键盘扫描码,然后采用映射表译成相应字符并放入tty读队列
read_q
。 然后通过中断处理程序do_tty_interrupt()
调用copy_to_cooked()
对该字符进行过滤处理,并放到tty辅助队列secondary
中,同时也把字符放入tty写队列write_q
当中并调用写控制台函数con_write()
,此时如果该终端的回显(echo )属性是设置了的,那么会直接显示到屏幕上。
do_tty_interrupt()
以及copy_to_cooked()
函数在tty_io.c
中实现。
con_write()
函数是在console.c
文件当中实现
总结来说:
主要涉及两个程序:键盘中断处理程序(keyboard.S
)负责把用户键入的字符放到read_q
缓冲队列当中;另外一个是屏幕显示处理程序(console.c
)用于从write_q
队列当中取出字符并显示到屏幕上。
基于以上认识,你就能明白大部分教程里面都有一张图,这张图展示了三个缓冲队列以及函数之间的关系,如下所示:
从键盘键入的数据可以写入文件,也可以回显到屏幕当中。我们只关心回显那条路。通过图中分析可知,我们只需要对console.c
文件(/linux/kernel/chr_drv
目录下)当中负责给终端写入字符的con_write
函数加以修改就OK。那么如何修改?
con_write()
函数往屏幕缓冲区写入的数据取决于是否按下f12, 因此我们需要时时刻刻监控是否按下f12。为此,我们可以定义一个全局变量switch_show_char_flag
来检测当前f12的状态,以及一个能够修改这个全局变量的回调函数。(这个回调函数不就是我们按下f12之后的中断相应函数么?)
在keyboard.S
当中定义了f12响应函数: