本节将更新哈工大《操作系统》课程第八个 Lab 实验 终端设备的控制。按照实验书要求,介绍了非常详细的实验操作流程,并提供了超级无敌详细的代码注释。
实验目的:
- 加深对操作系统设备管理基本原理的认识,实践键盘中断、扫描码等概念;
- 通过实践掌握 Linux 0.11 对键盘终端和显示器终端的处理过程。
实验任务:
本实验的基本内容是修改 Linux 0.11 的终端设备处理代码,对键盘输入和字符显示进行非常规的控制。 在初始状态,一切如常。用户按一次 F12 后,把应用程序向终端输出所有字母都替换为
*。用户再按一次 F12,又恢复正常。第三次按F12,再进行输出替换。依此类推。
| 文件名 | 介绍 |
|---|---|
| hit-操作系统实验指导书.pdf | 哈工大OS实验指导书 |
| Linux内核完全注释(修正版v3.0).pdf | 赵博士对Linux v0.11 OS进行了详细全面的注释和说明 |
| file1615.pdf | BIOS 涉及的中断数据手册 |
| hit-oslab-linux-20110823.tar.gz | hit-oslab 实验环境 |
| gcc-3.4-ubuntu.tar.gz | Linux v0.11 所使用的编译器 |
| Bochs 汇编级调试指令 | bochs 基本调试指令大全 |
| 最全ASCII码对照表0-255 | 屏幕输出字符对照的 ASCII 码 |
| x86_64 常用寄存器大全 | x86_64 常用寄存器大全 |
一、键盘输入处理
键盘中断发生步骤:
- 键盘 I/O 是典型的中断驱动,在
kernel/chr_drv/console.c文件中将键盘中断响应函数设为keyboard_interrupt。每次按键有动作,keyboard_interrupt函数就会被调用,函数定义在文件kernel/chr_drv/keyboard.S中; - 根据扫描码,查
key_table表进行扫描码处理,表中定义了相关所有扫描码对应键的处理函数,比如f1-f12键的处理则要先运行一段处理函数func; - 将扫描码放到键盘输入队列中,调用
do_tty_interrupt函数进行处理。
为了实现按
F12实现切换,只需要定义一个切换函数,并将其放在ket_table中F12对应的处理函数位置即可。
1、修改文件linux-0.11/kernel/chr_drv/tty_io.c,定义标志位,实现每按下一次F12标志位就会变化。
int switch_show_char_flag = 0;
void press_F12_handle(void)
{
switch_show_char_flag = switch_show_char_flag ? 0 : 1;
}2、修改linux-0.11/include/linux/tty.h文件,将标志位和函数声明为全局。
extern int switch_show_char_flag;
void press_F12_handle(void);3、修改linux-0.11/kernel/chr_drv/keyboard.S文件中key_table中F12对应的处理函数。
key_table:
/* .long func,none,none,none 58-5B f12 ? ? ? */
.long press_F12_handle,none,none,none /* 58-5B f12 ? ? ? */二、屏幕输出控制
屏幕输出过程:
- 输出字符到屏幕,系统调用
write函数来进行; write函数则会调用sys_write系统调用来实现字符输出;- 然后再调用
tty_write函数; - 最终调用
con_write函数将字符输出。
故只需要修改
con_write最终写到显存中的字符就可以了。具体修改文件linux-0.11/kernel/chr_drv/console.c,修改如下:
void con_write(struct tty_struct * tty)
{
// ....
switch(state) {
case 0:
if (c>31 && c<127) {
if (x>=video_num_columns) {
x -= video_num_columns;
pos -= video_size_row;
lf();
}
// 新增代码,若扫描码为大小写字母或者数字,则改为*
if(switch_show_char_flag) {
if((c>='A'&&c<='Z')||(c>='a'&&c<='z')||(c>='0'&&c<='9'))
c = '*';
}三、编译并运行
1、编译并运行
cd oslab_Lab7/linux-0.11
make all
../run2、测试结果
在 Bochs 中进行测试:
- 若没有按下
F12,输出为正常显示; - 若按下
F12,则数字和字母的回显变为*; - 且再次按下
F12,显示将恢复正常。