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

原创 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:有什么问题请留言,我会经常来看的 谢谢

自己动手写操作系统

转自:http://blog.csdn.net/littlehedgehog/article/details/2250362  磨刀不误砍柴工 刺猬@http://blog.csdn.net/...
  • a527606652
  • a527606652
  • 2013年01月27日 19:39
  • 991

自己动手写操作系统(一)

从去年就想好好的读一下这本书,跟着书上做一下,但是给耽搁了,现在就好好的开始探索这么书吧! 虽然我很想在这里吹一段这本书有多么的厉害,但是!我第一章都没有看完,吹不了!!!等我读的个七七八八再回来吹吧...
  • YuDale
  • YuDale
  • 2017年03月24日 21:11
  • 439

《自己动手写操作系统》源码解析——第三章pmtest5.asm

在pmtest4中,我们已经看到,对于非一致性代码,如何从低特权级转移向高特权级。但是我们该怎样从高特权级别,转移到低特权级别呢?一开始我们在实模式,是ring 0,我们怎样从ring 0到ring3...
  • trochiluses
  • trochiluses
  • 2014年02月27日 17:59
  • 1462

《自己动手写操作系统》—— 工作环境搭建

最近在看《自己动手写操作系统》 于渊著,看第一页头就蒙了,书上说要准备一张空白软盘,都2010年了,上哪去找软盘啊,自从接触计算机以来我还没见过软盘呢,估计要到科技博物馆才找得到吧,呵呵。其实在第二章...
  • feixiaku
  • feixiaku
  • 2014年07月14日 00:32
  • 2941

《自己动手写操作系统》第六章:从系统内核到进程A ring0>>ring1(一)

摘要:进程调度可谓是操作系统中最为重要的环节之一,在本文中,我们主要讲解进程模型、涉及的数据结构、如何从内核态转到用户进程?这一小节主要完成进程数据结构的分析,和从ring0>>ring1的进程开始阶...
  • trochiluses
  • trochiluses
  • 2014年03月18日 23:54
  • 1712

自己动手写操作系统——开发环境搭建

本文参考于渊老师写的《Orange S:一个操作系统的实现》一书。 参考文章: http://www.linuxidc.com/Linux/2016-10/135905.htm http://b...
  • zjdnwpu
  • zjdnwpu
  • 2017年04月16日 11:25
  • 414

《自己动手写操作系统》第三章a/pmtest1.asm

[html] view plaincopy  1 ; ==========================================    2 ; pmtest1.asm    3...
  • trochiluses
  • trochiluses
  • 2013年05月27日 10:31
  • 1877

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

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

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

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

学习《自己动手写网络爬虫》之记录1

某天突发奇想,想自己写一个网络爬虫,然后上网查了前辈们的经历,发现网络爬虫好处多多,于是坚定了自己的决心。再上网一找,看到好多人推荐这本书,于是就以这本书为参考来实现自己的网络爬虫了! 首先都是照着...
  • int_line
  • int_line
  • 2015年04月01日 11:23
  • 3195
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:《自己动手写操作系统》总结(下)
举报原因:
原因补充:

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