您的位置 首页 主动

需求了解Linux0.11-的发动引导进程

需要了解Linux0.11-的启动引导过程-在加载bootsect之前,bios从0地址开始加载了中断向量表————这个是我们的汇编代码中可以使用bios中断功能的基础。是在实模式中我们的原始武器和工具。按照一个中断向量占四个字节,7c00前面如果都是中断向量表的话,这里应该有7c00/4 = 7936个中断向量了。

发动搬家进程:

1、BIOS将磁盘引导块程序bootsect读入到内存0x7c00,开端履行指令;
2、bootsect将自己搬家到内存0x90000,跳到该段中的自己的下一条指令履行;
3、bootsect将设备检测装置程序setup读入到0x90200;
4、bootsect将内核映像system读入到0x10000,跳到setup头部0x90200履行指令;
5、setup获取体系参数,顺次保存在0x90000;
6、setup将system从0x10000搬家到0x0000;
7、setup设置硬件寄存器CPU状况字寄存器,进入32位保护形式,跳到system头部0x0000履行指令。
8、开端履行内核映像中的指令。
9、内核映像首部的指令(head.s)设置各个寄存器,加载中止描绘符表、大局描绘符表,检测芯片,
对16M内存进行分页。
10、履行main程序。

阅览三个汇编程序和注释,很快就能了解到发动引导程序在进入main函数前作了这些工作。
为什么要这样搬家和履行呢?
简略地讲,内核发动搬家进程是:bios装载运转bootsect,bootsect装载setup、system,运转setup搬家system。bios的行为是现已固定写好烧在主板上bios芯片里的了。不是linus所操控的,也不是操作体系的领域了。bios应该是和硬件架构严密相关的。所以为什么bios将bootsect读到0x7c00这么
个怪地址,也没有其它的好讲了————对架构我不明白。:(

       在加载bootsect之前,bios从0地址开端加载了中止向量表————这个是咱们的汇编代码中能够运用bios中止功用的根底。是在实形式中咱们的原始兵器和东西。依照一个中止向量占四个字节,7c00前面假如都是中止向量表的话,这儿应该有7c00/4 = 7936个中止向量了。应该没有这么多吧? 或许是有空余空间供扩展? 不得而知。
       bootsect自己搬家自己的行为,我没有找到充沛的理由。
setup被装载到0x90200,system被装载到0x10000,这些都没有掩盖到0x7c00+512的空间,也就不会形成自己装载的咚咚掩盖了自己的指令代码的风险。而这个bootsect的512字节巨细,至今也没有改变,也不该该是为后续扩展所保存的。从Linus讲setup直接load到0x90200能够看出,这个512字节也应该是不会变大的————因为bootsect是由bios装载的,变大了阐明bios的代码和行为都改变了,这个是不现实的。所以我能解说的理由便是:linus觉得bios加载的当地不爽,所以特意把它挪到0x90000和setup放在一同。假如你知道这个bootsect搬家的理由,请不惜告诉我

关于setup
setup被bootsect装载到了0x90200,bootsect履行完之后就履行了setup代码。setup被装载到0x90200,而不是其它的当地,应该是因为system占用了0x10000~0x90000,而bootsect占用了0x90000~0x90200。因为0x7c00+512地址曾经的当地被bios占用了。因而setup或许的装载的当地有:0x7c00+512后边,或许0x90200后边。而在setup代码的履行进程中有一个动作,将system从0x10000搬家到0地址。这样,因为预留的512K巨细的system必定把0~0x80000的内存都掩盖了。也便是说假如把setup装载在0x7e00之后,则会产生自己的搬家行为修正了自己的指令地址————这是不能够的。并且将setup装载在0x7e00,则setup的巨细受到限制,不能超越0x7e00到0x10000这块地址。setup获取的设备信息掩盖了0x90000的bootsect的代码。然后将system向0地址平移。这个动作掩盖了体系中止和0x7c00的bootsect。

这个时分为什么能够掩盖中止向量表呢? 我想是根据这么几个原因:
setup经过bios供给的这些东西能获取的体系参数都现已获取并保存了,东西现已没用了。在后边进入保护形式后,也现已不能经过中止向量的方法来运用bios中止了。前一个原因能够经过检查后边的汇编代码得到证明:后边的代码都没有再调用bios中止。第二个原因能够经过后续代码的动作和注释得到证明:setup位32位保护形式加载了大局描绘符表,中止描绘符表。 后续产生中止时,将经过中止描绘符表中的项映射到中止处理代码上去。这儿面本来中止向量的每一项应该是四个字节(我没有记错的话),而中止描绘符表中的项有八个字节————32位保护形式下,包括的中止信息更多了。

关于system
system便是Linux的内核了。内核首部的head.s的指令其实应该仍是算作引导程序。放在内核中,而不是像setup相同独自编出来,估量是为了后续版别更便利的修正吧————究竟内存分页、GDT、IDT之类的东西修正的或许性是很大的。

为什么将system从0x10000搬家到0地址,书上也说了,优点是关于其间的代码,线形地址和物理地址是相同的,这姿态写程序更便利一些————linus这样说。实际上,我感觉不搬家也没有什么不可。代码和数据的操作也应该没有什么不便利,究竟便是汇编里边也是运用的标号。或许仍是我没有了解到?

system加载了大局描绘符表,中止描绘符表。中止描绘符表现已说过了,用来映射中止服务程序和中止号的。大局描绘符表,则是用来描绘大局符号的。呵呵,这个解说。大局描绘符表是一个记载各个使命的相应段信息的大局表。表中两个字作为一个使命的描绘项:部分描绘符表LDT,使命状况段TSS。部分描绘符表指向某个具体使命的各个段信息(代码段,数据&仓库段)的结构。使命状况段TSS应该是用来记载使命状况进行使命调度用的吧? 从这儿看来,多进程的完成应该便是保存各个使命的上下文,进行切换和上下文处理吧。而上下文,也便是寄存器状况、指令方位、数据状况了。

head.s还对16M内存进行了分页。每4096字节的内存分为一页,用四个字节描绘一页(应该是四个字节的32位地址指向这一页的首部吧)。然后1024个页地址组成一个页表,一个页表占有一页(1024×4=4096)。一个页表也就办理了1024×4096=4M内存。Linus的16M内存即占用了四个页表来描绘。然后四个页表的地址又写到0地址开端的当地,占用了16字节,形成了页目录了。 页目录从0地址开端,页表从0x1000开端。也即第0页都是页目录了。依照Linus的这个处理,4096/4 × 4M =4G,也便是这个页目录的巨细能够办理4G内存了。不过假如真的初始化了4G的内存页,会出问题。4G内存需求1024个页表,一个页目录,供占用1025个页面,这样页表就写过了0x90000,要写到1025×1024=0x101000,比0x90200超越很远了————结果便是现在写到0x90200+0x400×2=0x90a00后边的大局描绘符表和中止描绘符表了。中止描绘符表无所谓,反正是哑中止。可是描绘符表被破坏了,后边的就没得玩了。

好了,大局描绘符表(多使命的容器)建好了,内存分页也做好了。 就等main来打展身手了。

 

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/ziliao/zhudong/99917.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部