《自己动手写操作系统》总结(下)

原创 2007年09月27日 19:10:00

上次说到了 将控制权交给内核,接下来的工作都由内核来完成。从这里开始,就可以用C语言来写了。(为什么?我还是不明白)但并不是内核全用C写,它依旧需要一个用汇编写得开头,让loader跳入进来。

跳进来后需要立即做一件事:切换堆栈。因为原来的堆栈在内存中的位置是在loader中,而将来loader是会被我们覆盖的,所以必须切换。设好堆栈也是调用C函数的前提条件。这里说一下,所谓的堆栈只是一段连续的内存,你分配好内存后,只要将这段内存的最高地址赋给ESP(还有段寄存器SS也要相应处理),那这段内存就是当前所用的堆栈了。

接着要切换GDT,就是把就的GDT复制到自己希望的内存地址中,可以用C语言完成。注意! 在使用 C 代码的时候一定要保证 ds, es, ss 这几个段寄存器的值是一样的,因为编译器默认它们是一样的。(这里又想到了平坦内存模型的问题。这种模型有什么优势或者好处?对于系统保护有什么意义?问题还有好多)把GDT放在什么位置也是需要考虑的,因为这张GDT在今后一直需要用到,不能被其他内容所覆盖,所以需要考虑内存的布局。

接着是初始化中断处理,包括设置8259A和IDT。IDT有256项,但并不需要全部都初始化。接着就是中断处理函数(需要用汇编写,中间可以调用C函数)。好了之后加载IDT。这都挺简单的。这些好了之后,如果因为代码编写出现问题而导致异常,系统就不会自动崩溃,而是调用相应中断处理函数(我碰到的最多的就是#GP,主要是跳转地址错误……尤其是中断返回的时候)。

接下来讲的是进程。感觉书中只是对进程在内核中的表现形式做了介绍。每个进程需要一个LDT来支持,这很简单,和GDT一样,就不多说了。重点主要是进程的中断和切换的原理。进程要能在被中断后恢复,就需要把在进程中断前一刻的所有寄存器值全保存下来,在恢复时只要把全部寄存器值还原,进程就可以像什么都没发生过一样继续运行。

如何保存?我们知道在中断发生时,会把返回地址和标志寄存器压栈,同时由于特权级转换,还会把原ss和esp压栈,然后切换堆栈(TSS)。所以需要模拟一个堆栈的数据结构(进程表),来存放所有寄存器的值(cs和eip是不能用push压栈的),然后在中断产生前,设置好TSS中的esp0值,指向该结构的顶端。中断程序中则push相应寄存器(由于目前esp是取得TSS中esp0的值,所以寄存器被压进了进程表中保存起来),然后切换到内核栈。

而切换进程则是在中断结束前,重新设置好esp0(指向目标进程表的顶端,为下次中断准备)和当前esp值(指向目标进程的进程表底端),然后恢复相应寄存器,中断返回即可,这样所有寄存器都被还原,esp也被切换到了目标进程运行时的堆栈。

这挺复杂的,需要多多体会。

有个问题是,上面的实现都必须要有特权级切换,才能切换堆栈,完成我们的任务。这是不是说不发生特权级切换的话就不能进  行进程切换的工作?还是有什么别的方法?

编写中断程序也是一件很艺术的事,说不清,需要多看代码,才能体会。其实对中断,我还有许多的不了解,比如中断重入。控制是否接收中断的条件有,1:eflags中的中断屏蔽标志位,用sti和cli控制,2:8259A中的EOI,3:8259A中的屏蔽寄存器。3不是在中断程序中控制的,不与讨论。中断发生后,我们需要重置EOI,才能使8259A继续接受后面的中断。8259A中还有一个寄存器,保存还未处理的中断。我还没看过详细的资料,所以接下来的纯属猜测。当有中断产生,8259A先看自己的中断屏蔽寄存器,如果中断没有被屏蔽,则放入中断服务寄存器。8259A会检查EOI位,如果是1则表示CPU正在处理中断,不做任何事情,如果为0且中断服务寄存器中有中断,则发送中断请求。而CPU会按照eflags的标志予以处理和抛弃。

进入中断后硬件会自动关闭中断标志,所以如果允许中断重入,需要sti。我们还需要重置EOI。这时8259A则同时会重置中断服务寄存器中相应的位,表示中断结束(EOI只有一位,而中断服务寄存器中有很多位,如何对应?猜测是自动复位最高优先级位)。

中断就此说完,接下去的内容我也没好好看过,所以暂时就不说了。下一篇文章介绍硬盘控制器编程^_^

至此,结束。

PS:有什么问题请留言,我会经常来看的 谢谢

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

《自己动手写操作系统》 第一章总结

《自己动手写操作系统》 第一章总结俗话说万事开头难,为了督促自己能在假期好好学习,打算认真做一下学习笔记。先记录一下在学习过程中遇到的问题和解决方案:自己动手写操作系统 第一章总结 书籍和工具下载地址...

自己动手写操作系统 第四章总结

自己动手写操作系统 第四章总结 本章主要内容是建立一个功能比较完善的引导扇区也称为 boot sector 首先回顾一下一个操作系统从开机到运行的过程 1.引...

自己动手写操作系统一书的总结

Orange 总结Orange分为Boot部分,load部分和内核kernel部分:具体内存分布如下图所示:系统启动过程:bios加载boot部分(512byte)于内存7c00h处并跳转到7c00h...

《自己动手写一个操作系统》个人实践1

根据《自己动手写操作系统》一书个人的实践,用ubuntu14制作 boot.bin 开始步骤: 注意: 如果在安装ubuntu14系统过程中没有设置root密码,安装完后 在ubuntu14中通过命令...

《自己动手写操作系统》多进程代码分析

主要的代码有三部分:(在chapter6\k\kernel中)   (1)kernel.asm中时钟中断处理的部分:    ; 中断和异常 -- 硬件中断 ; ---------...

《自己动手写操作系统》第三章 pmtest9源码解析——中断处理程序

本节,我们将学习现代操作系统的一个重要的特点——中断处理机制。同样,中断处理也是软硬件协同完成的,其中硬件部分:8259A负责可编程中断控制器,通过读写端口,实现中断信号和中断号的绑定等工作;CPU通...

全面剖析《自己动手写操作系统》的pmtest1.asm

段机制轻松体验 内存寻址: 实模式下的内存寻址: 让我们首先来回顾实模式下的寻址方式 段首地址×16+偏移量 = 物理地址 为什么要×16?因为在8086CPU中,地址线是20位,...

自己动手写操作系统

转自:http://blog.csdn.net/littlehedgehog/article/details/2250362  磨刀不误砍柴工 刺猬@http://blog.csdn.net/...

开篇:学习 《自己动手写操作系统 》于渊

操作系统启动流程:开电源->加电自检->寻找启动盘->若为软盘则检查0面0磁道0扇区,并寻找是否以0xAA55结束,若是,则BIOS认为是一个引导扇区。此段代码应少于512字节,启动跳转到该段代码后,...

自己动手写操作系统

《自己动手写操作系统》读后感                http://blog.csdn.net/zgh1988/article/det...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)