1654_MIT 6.828 JOS entry.S实现分析

时间:2021-03-01 01:09:42

         全部学习汇总: GreyZhang/g_unix: some basic learning about unix operating system. (github.com)

         之前分析过JOS中的启动代码的启动实现,也知道接下来会按照存储区的地址去调用内核。这一次看一下内核的entry.S文件的设计实现。分析一下内核启动初级阶段的一些工作。。

1654_MIT 6.828 JOS entry.S实现分析

         最前面的代码先跳过去,先看这部分注释说明。内核在链接的时候会链接到一个指定地址(KERNBASE + 1M)开始的存储区,而BootLoader加载内核的时候会把内核加载到1M开始的存储区。这样,加载之后,内核镜像的信息其实是与链接中的信息差了一个KERNBASE的差距。RELOC的功能是消除掉这个差距,让LINK后的信息变成与加载存储区一致的效果。从这个意义上讲,这个功能也就是在实际的物理存储中根据内核信息解析数据的时候会用到的一个转换。

1654_MIT 6.828 JOS entry.S实现分析

         这一部分代码,首先按照4字节对齐的方式定义了3个数值。接着,计算了一个_start的数值,这个其实是entry在被BootLoader加载到物理存储之后的实际位置。之后的热启动,暂且不知道四一个什么机理,先跳过。

1654_MIT 6.828 JOS entry.S实现分析

         继续往下的代码,给两个控制寄存器赋值。这两个寄存器分别是CR3和CR0。

1654_MIT 6.828 JOS entry.S实现分析

         先看CR3,这个是最先被操作的。

1654_MIT 6.828 JOS entry.S实现分析

         CR3,现在其实是存储了上面这个数组在实际物理存储中的地址信息。从命名看,跟描述是符合的,这里存储的是页目录的地址信息。而这个页目录,就是上面这个1K个元素的数组。

1654_MIT 6.828 JOS entry.S实现分析

         接下来看CR0控制寄存器,这里面的信息还是很多的,结合上面的表格,可以知道这一次的操作主要是做了这几个操作:1,开启了保护模式; 2,启用了内存分页; 3,开启了写保护的功能。

1654_MIT 6.828 JOS entry.S实现分析

         完成上面的操作之后,跳转到了当前汇编代码中的另一段。

1654_MIT 6.828 JOS entry.S实现分析

         接下来的操作,就是准备了C语言工作的堆栈条件,之后跳转到了C语言中。后续,功能按照C语言的逻辑来进行分析即可。这里面,其实有一个点没有分析,因此也会导致后续的逻辑分析对不上。这个没分析的点就是页目录等信息是如何起作用的。其实,这个很容易理解最终的意图:让软件能够把链接分配的地址信息成功跟使用的物理地址形成准确的映射。关于这个关键点的分析,后面单独在看。