1. 第15章代码修改
先不说习题,说一说我对源码的修改。从运行结果来看,主要是增加了颜色支持。不过把我的代码与配书代码相比较的话,还是有很多不同的。这些修改是怎么来的,可以参考我之前的博文。
运行效果如下图
2. 习题解答
请注意,我是在上面的修改的基础上完成了习题,下文的截图是习题代码和上面修改后的代码进行对比的截图。
虽然我的答案不是那么漂亮,但是经测试符合题目要求,所以写出来和大家讨论。囿于篇幅,我只讲解关键的部分,一些不那么重要的修改(比如修改了字符串的内容等)就不赘述了。
2.1 第一题
修改本章的源程序,使之能够顺序完成以下工作:
(1)从程序管理器任务切换到任务A,显示消息后返回程序管理器;
(2)从程序管理器任务切换到任务B,显示消息后返回程序管理器;
(3)再从程序管理器任务切换到任务A,显示另一条消息,然后返回程序管理器;
(4)再从程序管理器任务切换到任务B,显示另一条消息,再返回程序管理器;
解答:首先,我对terminate_current_task
这个过程进行了修改。红色是添加的部分。
分析:(1)和(2)很好实现,因为配书源码已经帮我们做了。需要注意的是(3),当再从程序管理器任务切换到任务A的时候,注意,这时候还在A的全局空间,所以必须对terminate_current_task
加上retf
(第497行),这样才能返回到A的用户空间,然后打印另一条消息。
第471~472行,用内核数据的选择子core_data_seg_sel
加载了用户程序的DS,如果不返回用户空间,还没有什么大的影响;但是,一旦返回,因为需要改变特权级,CPU就会则检查DS,ES,FS和GS的内容,如果段选择子指向数据段或者非一致代码段且段描述符的DPL在数值上小于返回后的新CPL,那么就把数值0传送到该段寄存器。
如果忘了这个知识点,可以参考我的博文调用门详解的末尾部分。
所以,461~464用于保存用户程序在用户空间的“现场”,第493~496用于恢复“现场”。
其次,填写用户TSS信息的时候,我增加了对ESP的填写。配书代码没有,我觉得这是一个BUG。虽然不填写也不会影响实验结果,但是从严谨的角度讲,有必要填写,不然用户的ESP就是一个不确定的值,很可能造成“灾难”。
最后,内核代码末尾增加了切换相关的代码。
需要注意的是第1148和1157行,作用都是取得TCB的基地址。
另外,用户程序也有修改。
下图显示对字符串有修改。
下图显示在用户程序末尾增加了一段。
最后,程序的运行结果是
第二题我们下次再说。敬请期待…
附:
修改代码下载地址:
http://download.csdn.net/detail/u013490896/9573297
习题代码下载地址:
http://download.csdn.net/detail/u013490896/9578126