注意阅读PPT以及实验报告上的提示哦~

本实验包含 2 关,要求如下:

Phase 1:

键入 F12,激活*功能,键入学生本人的姓名拼音,首尾字母等显示*

比如:zhangsan,显示为:*ha*gsa*

Phase 2:

键入“学生本人的学号” :激活*功能,键入学生本人的姓名拼音,首尾字母等显示*

比如:zhangsan,显示为:*ha*gsa*,

键入“学生本人的学号-” :取消显示*功能

提示:完成本实验需要对 lab4/linux-0.11/kernel/chr_drv/目录下的 keyboard.s、console.c 和 tty_io.c 源文件进行分析,理解按下按键到回显到显示频上程序的执行过程,然后对涉及到的数据结构进行分析,完成对前两个源程序的修改。修改方案有两种:

1、在 C 语言源程序层面进行修改

2、在汇编语言源程序层面进行修改其他说明见 实验四.ppt 。linux 内核完全注释(高清版).pdf 一书中对源代码有详细的说明和注释。

实验步骤及实验分析

准备环境。

1.在官网下载VMware Workstation 15 Player

下载网址:

https://customerconnect.vmware.com/en/downloads/info/slug/desktop_end_user_computing/vmware_workstation_player/15_0

注意:安装时勾选增强型键盘驱动程序。

2.下载Linux-Ubuntu 16.04.1(Ubuntu 16.04.1-sesktop-i386.iso)

下载地址:

http://old-releases.ubuntu.com/releases/xenial/

3.打开VMware Workstation 15 Player,创建虚拟机,镜像文件选择(.iso文件)上一步下载的。取消自动版本更新。按提示软件更新:安装VMeare Tools for Linux。

4.安装gcc-3.4

搜索栏输入cmd打开小黑框,按照PPT内容,依次输入指令wget…与sudo qpkg…,安装gcc-3.4。

5.拷贝文件

将老师下发在群中的压缩包linux-0.11.tar.gz直接拖拽到linux虚拟机中。之后解压。

tar -xvf linux-0.11.tar

解压后在原目录出现文件夹lab4。在lab4文件夹中有linux-0.11文件夹。按照实验报告中的提示,keyborad.S和console.c文件在目录lab4/linux-0.11/kernel/chr_drv。

cd lab4/linux-0.11/kernel/chr_drv

6.更新软件(问题与解决方式)

问题:我在调试过程中发现make clean之后无法完成make

解决方式:安装bin86。代码:

sudo apt-get install bin86

问题:发现用vi编辑器编辑程序时,由于vi版本问题,按下上下键会输入a和b,并且不能删除内容,敲错代码没法修改只能重开

解决方式:下载vim。代码:

sudo apt-get install vim

阶段一

按照PPT提示,查看keyboard.s。

vi keyboard.S(如果已经下载vim则可以:vim keyboard.S)

查看keyborad.S中的func()函数。参考补充教材P438,代码第225行:判断是否按下了功能键F12。226行:不是,则不处理,返回。因此可以在226行后增加一行代码,跳转至更改f12Flag的函数:

call change_f12Flag

把change_12Flag()放在console.c中,并添加全局变量f12Flag。

在console.c中

将字符c在写到内存pos处前,将其更改为*。

添加代码:

if(f12Flag &&((c>64&&c

注意,是要更改自己性命的首字母与尾字母,比如我的首位字母分别的w与n,所以当c是w与n时才更改为*。

更改完毕。回到目录lab4/linux-0.11/下,编译。执行命令:

make clean

make

回到目录lab4/下,执行命令:

./run

阶段一运行结果:

阶段二

更改console.c,使得在输入学号后直接输入性命则加密,在输入学号后输入-再输入性命则解密。

在函数内增加变量count用于记录学号是否输入正确,增加变量num用于判断加密或解密。

更改函数主体,如图所示。注意每个人学号的不同,判断学号的代码段是不同的。

阶段二运行结果如下:

终端基本数据结构

这一部分摘自 linux 内核完全注释(高清版).pdf 一书中的原文内容,我也不能完全理解,只是文字的搬运工。

链接:https://pan.baidu.com/s/1s_D17NDkyT_RDJmu_mOeaw

提取码:45mh

每个终端设备都对应有一个tty_struct数据结构。该结构体定义在include/linux/tty.h文件中,其结构如下:

struct tty_struct{
struct termois termios;//终端io属性和控制字符数据结构
int gprp;//所属进程组
int stopped;//停止标志
void(*write)(struct tty_struct*tty);//tty写函数指针
struct tty_queue red_q;//tty读队列
struct tty_queue write_q;//tty写队列
struct ttty_queue secondary;//tty辅助队列(存放规范莫属字符序列)
};//可称为规范(熟)模式队列
extern struct tty_table[];//tty结构数组

终端所处理的数据被保存在3个tty_queue结构的字符缓冲队列中(或称为字符表):

struct tty_queue{
unsigned long data;//等待队列缓冲区中当前数据统计值
//对于串口终端,则存放串口端口地址
unsigned long head;//缓冲区中数据头指针
unsigned long tail;//缓冲区中数据尾指针
struct task_struct*proc_list;//等待本缓冲队列的进程列表
char buf[1024];//队列的缓冲区
};

控制台终端由内核中的键盘中断处理程序keyboeard.s和显控制程序console.c进行管理。它接收上层tty_io.c程序传递下来的显示字符或控制信息,并控制在主机屏幕上字符的显示,同时控制台(主机)把键盘按键产生的代码经由keyboard.s传送到tty_io.c程序去处理。

keyboard.s和console.c这两个程序实际上是linux系统主机中使用显示器和键盘模拟一个硬件终端设备的仿真程序。

在linux0.11内核中,终端控制台驱动程序涉及keyboard.S和console.c程序。keyboeard.S用于处理用户键入的字符,把它们放入读缓冲队列read_q中,并调用copy_to_cooked()函数读取read_q中的字符,经转换后放入辅助队列secondary。console.c程序实现控制台终端受到代码的输出处理。

总的来说,keyboard.S主要用于把用户键入的字符放入read_q缓冲队列中,console.c用于从write_q队列中取出字符并显示在屏幕上。