“操作系统实验”实验报告

终端设备的控制

实验名称:终端设备的控制

实验日期:2021年6月3号

班级:物联网193班

姓名:邹胡健

学号:1930110718

一、实验目的

  • 1、实验相关知识阐述:

  • 本实验的基本内容是修改 Linux 0.11 的终端设备处理代码,对键盘输入和字符显示进行非常规的控制。 printf() 等输出函数最终都是调用 write() 系统调用,所以控制好 write(),就能控制好输出字符。

  • 2、实验原理的预习情况:

  • 回答问题:

  • 在原始代码中,按下 F12,中断响应后,中断服务程序会调用 func?它实现的是什么功能?

  • 答:正常情况下打开模拟器中,按下功能键F12即可显示内核栈中各个进程的状态信息,而当把func中的call show_stat屏蔽掉后,再按下F12就什么也没有了,可见func实现的功能就是调用show_stat函数来显示内核栈中各个进程的状态信息。

  • 在你的实现中,是否把向文件输出的字符也过滤了?如果是,那么怎么能只过滤向终端输出的字符?如果不是,那么怎么能把向文件输出的字符也一并进行过滤?

  • 答:只过滤了向终端输出的字符,向文件输出的字符没有被过滤。因为我们最后修改的是控制向显存输出的con_write()函数,使其当flag=1的时候向显存输出星号。如果要过滤掉向文件输出的字符的话,需要找到对应的那个控制向文件输出的函数并修改。

  • 3、实验注意事项:

  • 本实验需要修改 Linux 0.11 的终端设备处理代码(kernel/chr_drv/console.c 文件),对键盘输入和字符显示进行非常规的控制。

二、实验环境

  • oslab实验室

三、实验内容

  • 实验目的

  • 加深对操作系统设备管理基本原理的认识,实践键盘中断、扫描码等概念;

  • 通过实践掌握 Linux 0.11 对键盘终端和显示器终端的处理过程。

  • 实验原理

  • 键盘 I/O 是典型的中断驱动,在 kernel/chr_drv/console.c 文件中:

void con_init(void)  //控制台的初始化
{
    // 键盘中断响应函数设为 keyboard_interrupt
    set_trap_gate(0x21, &keyboard_interrupt);
}
copy
  • 所以每次按键有动作,keyboard_interrupt 函数就会被调用,它在文件 kernel/chr_drv/keyboard.S(注意,扩展名是大写的 S)中实现。
  • 所有与键盘输入相关的功能都是在此文件中实现的,所以本实验的部分功能也可以在此文件中实现。
  • 简单说,keyboard_interrupt 被调用后,会将键盘扫描码做为下标,调用数组 key_table 保存的与该按键对应的响应函数。

四、实验步骤

  • 环境准备
cd oslab
tar -zxvf hit-oslab-linux-20110823.tar.gz -C /home/shiyanlou
copy
  • 在/kernel/chr_drv/keyboard.S中,删除call show_state.原代码中,F12用来显示进程信息,现在我们按下F12不需要该功能,注释掉。
func:
    push %eax
    push %ecx
    push %edx
    //call show_stat
    pop %edx
    pop %ecx
    pop %eax
copy

图片描述

  • 修改/kernel/chr_drv/tty_io.c文件。其中的copy_to_cooked函数是处理ASCII字符的函数。先在该函数的定义外面增加全局变量如下,flag即开关标志,f1~f3是等会判断要用到的一些中间变量。F12键的扫描码是ESC、[、[、L,它们对应的ASCII码是27,91,91,76,也就是说我连续判断四次字符,如果正好对应F12的ASCII码,那么就改变开关flag。
int flag = 0;
int f1=0,f2=0,f3=0;
copy

图片描述

copy_to_cooked函数添加如下:

void copy_to_cooked(struct tty_struct * tty)
{
    signed char c; 
    while (!EMPTY(tty->read_q) && !FULL(tty->secondary)) {
        GETCH(tty->read_q,c);
//开始添加
if(c==27){
            f1 = 1;
            f2=f3=0;
        }
        else if(f1==1 && f2==0 && c==91){
            f2 = 1;
        }
        else if(f2==1 && f3==0 && c==91){
            f3 = 1;
        }
        else if(f3==1 && c==76 && flag==0){
            flag = 1;
            f1=f2=f3=0;
            continue;
        }
        else if(f3==1 && c==76 && flag==1){
            flag = 0;
            f1=f2=f3=0;
            continue;
        }
        else{
            f1=f2=f3=0;
        }
//添加结束
copy

图片描述

  • 为了实现按下F12键,文字变为“*”的功能,我们修改/kernel/chr_drv/console.c中的con_write()函数,添加if语句
  • 要添加声明!!!
    extern int flag;
    
    copy

图片描述

//添加开始
if(flag == 1){
    c = '*';
}
//添加结束
__asm__("movb attr,%%ah\n\t"
"movw %%ax,%1\n\t"
::"a" (c),"m" (*(short *)pos)
);
copy

图片描述

  • 编译 图片描述
  • 运行BIOS 输入ls,按下F12后输入的内容变为“**”,再按下F12后恢复 图片描述

五、实验总结

  • 这次实验不同于之前做的系统调用等等,需要多次修改系统中的文件,这次实验的主要目的是让我熟悉设备管理。我将理论知识与实践相结合,较为顺利地实现按下一个功能键完成特定功能的任务。通过这次实验,我熟悉了设备管理的基本知识,也为今后的学习打下了基础。
最新评论
暂无评论~