实验名称:终端设备的控制 实验日期:2021/7/6
班级:物联网193 姓名:沈俊杰 学号:1930110716 二、实验环境: linux操作系统
三、实验内容: 本实验的基本内容是修改 Linux 0.11 的终端设备处理代码,对键盘输入和字符显示进行非常规的控制。
在初始状态,一切如常。用户按一次 F12 后,把应用程序向终端输出所有字母都替换为“*”。用户再按一次 F12,又恢复正常。第三次按 F12,再进行输出替换。依此类推。
四、实验过程及数据记录: 第一个地方: 正常情况下在linux0.11中,当按下F1~F12的功能键后会调用show_stat函数来显示系统中当前进程状态,对应代码在kernel/chr_drv/keyboard.S文件中,第210行func函数中,如下图(在vim中直接用/搜索show_stat即可跳到对应位置,如果不是就按n去找下一个)。
func: push %eax push %ecx push %edx call show_stat pop %edx pop %ecx pop %eax 现在我们不需要按下F12显示进程状态了,所以把call show_stat删去,我们需要的是调用一个起到开关功能的函数,在这里我把函数名设为Change_flag,所以修改成如下:
func: push %eax push %ecx push %edx call Change_flag pop %edx pop %ecx pop %eax 所以接下来我们需要在kerner/chr_drv/console.c文件中新增这个Change_flag函数,该函数如下:
int flag = 0;
void Change_flag(void){ if (flag == 0){ flag = 1; } else{ flag = 0; } } 第二个地方: 在kernel/chr_drv/console.c文件中定义的con_write()函数中,它对队列中的字符进行了一些处理后,最终放入显存。如下是将字符变量c放入显存的代码:
asm("movb attr,%%ah\n\t" "movw %%ax,%1\n\t" ::"a" (c),"m" (*(short *)pos) ); 所以我们只需要在这段代码之前加上一条if语句,判断flag如果是1,则把要放入显存中的字符变成星号,修改后如下(如果刚才是采用第二种方法的话,需要在该函数中先通过extern int flag;这条语句来声明外部变量 ,因为flag在现在的这个c文件中还没有定义过):
//添加开始 if(flag == 1){ c = ''; } //添加结束 asm("movb attr,%%ah\n\t" "movw %%ax,%1\n\t" ::"a" (c),"m" ((short *)pos) ); 修改完后编译内核,打开模拟器即可测试。按下F12后,随便输入一些内容,屏幕上的回显变成星号,再次按下F12后,输入一些内容,回显的内容恢复正常。 五、实验结果分析: 在原始代码中,按下 F12,中断响应后,中断服务程序会调用 func?它实现的是什么功能? 答: 会调用func函数, 调用show_stat打印当前进程信息.
在你的实现中,是否把向文件输出的字符也过滤了?如果是,那么怎么能只过滤向终端输出的字符?如果不是,那么怎么能把向文件输出的字符也一并进行过滤? 答: 没有, 修改文件输出中类似con_write函数.
六、实验心得: 通过这次实验,我学会了对终端设备进行控制,修改终端设备处理代码,让我对操作系统的实验有了更加深入的理解
学习时间 75分钟
操作时间 33分钟
按键次数 2508次
实验次数 6次
报告字数 1618字
是否完成 完成