基于内核调试与抽象精化的操作系统实验设计

2019-08-24 08:57文艳军李姗姗刘江潮
计算机教育 2019年8期
关键词:内核实验设计进程

文艳军,罗 宇,李姗姗,刘江潮

(国防科技大学 计算机学院,湖南 长沙 410073)

1 研究背景

操作系统实验设计的一个难点问题是如何使学生比较容易地掌握操作系统内核的工作过程,从而真正弄懂内核。目前学界的操作系统内核实验设计主要有以下几种做法。

(1)要求学生从一个基本框架出发,逐步开发出一个基本可用的操作系统,例如MIT的6.828课程使用JOS操作系统,伯克利加州大学的CS162课程使用Pintos操作系统,哈佛大学的CS161课程使用OS/161操作系统,清华大学使用ucore操作系统,浙江大学使用Lcore操作系统[1]等。

(2)要求学生对一个已经基本可用的操作系统进行分析、改写或扩充。例如MIT的6.828课程同时使用xv6操作系统,荷兰阿姆斯特丹Vrije大 学 的Andrew S.Tanenbaum使 用MINIX 3, 哈尔滨工业大学的李治军等使用Linux 0.11操作系统[2],北京英真时代科技有限公司开发的操作系统课程也使用Linux 0.11操作系统[3]。本教 学组也在Linux 0.11上开发过一组内核调试分析实验[4]。

(3)要求学生对一个商用级别的操作系统进行分析或改写。例如西安邮电大学的陈莉君等使用高版本Linux[5],以前也有一些学校使用Open Solaris和WRK[6]。典型做法是增加内核模块和驱动程序等。

上述探索有力地促进了学生对操作系统内核的掌握,成效显著。与此同时,降低难度与取得整体性认识难以两全。从基本框架出发写出一个可用操作系统难度大,尤其在开始阶段,需要首先掌握大量CPU编程细节,导致启动门槛高,学习曲线陡峭。分析改写一个已经基本可用的操作系统或者商用级操作系统又很难获得整体性认识,因为系统已经很复杂了:xv6有近1万行代码,Linux 0.11有近15000行代码,Linux 4.4则有近2000万行代码。本教学组大规模使用调试手段分析内核特定路径,有助于降低难度并取得较好的整体性认识。但在以前的设计中,对一条执行路径只分析一次,直接分析该路径上详细的状态变化,一次暴露所有细节。这导致依然存在需要首先掌握大量CPU编程和操作系统设计细节、启动门槛高的问题。

抽象精化思想在程序分析和验证领域有广泛应用[7],基于内核调试和抽象精化的操作系统实验设计方法的基本思想是:对每条内核执行路径分析多遍,分析时不一次暴露所有细节,而是进行抽象,一开始只观察少量细节,即作一个高层抽象,在后面再次分析时逐渐加入更多细节,对抽象进行精化、降低抽象程度,逐步贴近完整的复杂底层状态,见图1。

2 内核执行路径及其调试

内核实验主要围绕两条内核执行路径展开,其目的是使内核执行一些特定的功能模块,满足实验内容需要。路径1见图2,修改了内核main函数(部分),针对的是中断与异常、进程管理和内存管理等内核功能。按此路径运行时,内核会创建两个进程:0号进程和1号进程,分别循环输出字符‘0’和字符‘1’。运行时,会先执行0号进程(图2的轨迹‘1’),然后切换到1号进程(轨迹‘2’),再切换回0号进程(轨迹‘3’),最后在时钟中断处理时切换到1号进程(轨迹‘4’)。这条路径涉及段页式内存管理、用户态与核心态的相互转换、fork系统调用、时钟中断处理、进程调度和进程切换等知识点。

图2 内核执行路径1

路径2见图3,只修改了内核init函数,针对的是设备管理和文件系统等内核功能。按此路径运行时,内核也会创建两个进程:0号进程和1号进程,0号进程空转,1号进程会执行init函数,先加载根文件系统(代码块‘1’),然后打开控制台终端(代码块‘2’),接着输出提示信息并等待用户输入(代码块‘3’),再将文件/usr/root/hello.c的内容读出、显示,并写到文件/usr/root/hello-new.c中(代码块‘4’),最后执行同步操作,将修改过的内存缓冲区内容写入外存(代码块‘5’)。这条路径涉及字符设备、块设备和普通文件的打开、关闭和读写等知识点,也在一定程度上涉及路径1的知识点。

实验时,学生将沿着这两条路径对Linux内核进行调试,观察CPU寄存器和内存的状态变化,并进而对内核进行部分改写。我们建立了方便的实验环境,利用Bochs虚拟机软件的调试功能,可以在Ubuntu中对内核进行源码级(使用gdb)和汇编级调试(使用bochdbg)。

图3 内核执行路径2

3 基于抽象精化的内核实验设计

基于操作系统原理课程设计了5个内核实验,分别与教材[8]的第2、3、5、6、7章配套。在原理授课时,同步讲授实验原理,引导学生进行调试分析,要求学生在课外对内核进行深入的调试分析和改写,同步完成实验。这些实验的基本情况见表1。

这些实验覆盖了操作系统内核的各主要模块,每个实验的内容包括调试分析和改写两部分,具体见表2。

三个实验的分析对象是内核执行路径1,后两个实验的分析对象是内核执行路径2。

正如前文所述,为了降低难度、使学习曲线更平滑,采用抽象精化思想来设计这些实验。在完成这些实验时,需要学生关注的状态信息是由少逐步变多的,调试时不用看懂所有细节,只需弄懂要求的部分信息即可。具体而言,每个实验关注的状态信息主要包括3类:CPU寄存器、操作系统内核数据结构、操作系统内核的函数调用事件,具体见表3。

其中‘+’表示在前序实验关注状态信息的基础上再增加一些信息,当然不一定所有前序信息都需要在本实验中观察,但总体而言观察的信息是递增的。以CPU寄存器为例,4个特殊段寄存器(IDTR、GDTR、TR、LDTR)是在前3个实验中逐步引入的,其中涉及的复杂段页式地址转换过程被逐步介绍,难度得到分解。完成前3个实验后,X86 CPU的特殊寄存器就基本介绍完了。

正是因为采用了这种抽象精化的思想,复杂性被逐步引入,当学生完成所有5个实验后,对Linux 0.11内核的掌握已经很深入了。

4 教学实施效果

表1 实验概况

本实验方案在国防科技大学计算机学院2018年秋的操作系统原理课中进行了实施,实验与原理课同步开展。班上共27名学生,所有学生都达到了及格标准,且优秀和良好的学生占了绝大多数。

表3 各实验关注的状态信息

此外,课程结束后进行了匿名问卷调查,收到关于实验难度的反馈25份,其中反映“实验容易,需要增加难度”的有1人,反映“实验难度适中,不用增加难度”的有21人,反映“实验难,应该降低一些难度”的有3人。

综合来看,按照本实验设计方案,在保证较好的实验深度的同时,内核实验的难度得到了有效控制。

同时,该模式存在一些有待改进的地方:部分能力强的学生希望提高内核改写的规模和难度。可以考虑为这类学生设计更具挑战性的内核实验。

5 结 语

这种基于调试分析和抽象精化的操作系统内核实验设计方法,设计了一组Linux 0.11内核调试分析与改写实验,并在操作系统课中进行了试验,取得了良好效果,内核实验的难度得到分解,启动门槛降低。后续工作将针对不同基础的学生设计一些可选实验,进一步完善实验设计方案。

猜你喜欢
内核实验设计进程
多内核操作系统综述①
吹蜡烛
有趣的放大镜
有用的电池
强化『高新』内核 打造农业『硅谷』
活化非遗文化 承启设计内核
有效把握政治新形势 积极推动党建工作进程
债券市场对外开放的进程与展望
微软发布新Edge浏览器预览版下载换装Chrome内核
快速杀掉顽固进程