操作系统实验Ucore:bootmain(二)

本文首发于我的博客
书接上回,我们继续来看ucore操作系统的启动部分。

上一部分结束时,程序已经从最开始的bootasm跳转到了bootmain函数。

1. 读取磁盘

由于BIOS只会把第一个扇区加载到磁盘上,而我们的操作系统的大小肯定不止512KB,所以要在boot程序中把操作系统其余的部分加载到内存上。
在这里插入图片描述
总体来看,这个函数的意思就是将磁盘上从1开始的8个扇区加载到ELFHDR(0x1_0000)的位置上。由于第0个扇区(就是我们现在正在执行的代码)已经被BIOS加载上了,所以从第一个扇区开始加载就行了。

至于为什么是这样组织磁盘的,就要看Makefile里的描述了
在这里插入图片描述
这里的意思是,先制作一个大小为1000个block(512Byte)的img文件,然后把 bootblock,就是bootasm + bootmain放在第零个块中,再从第一个块开始,放入kernel

注意在制作bootblock时会用sign.c(tool目录下的)将其填充为510byte并在最后加上55AA使其成为一个合法的主引导扇区
在这里插入图片描述
构造完成后各文件大小如上图

再回到读取扇区的代码上来在这里插入图片描述
这段代码就是循环的调用readsect函数,把count个byte的数据读取到va开头的地址上。在这里插入图片描述
readsect函数用于读取一个扇区到指定位置,关于读取扇区的描述,可以看我之前写的博客。这里看反汇编出来的代码会更详细一些。

总而言之,就是与0x1F0到0x1F7这八个端口交互数据。

2.解析ELF

和bootblock不一样,kernel是ELF格式的,所以我们需要先解析处kernel中的一些信息。关于ELF,可以参考
文档

《程序员的自我修养:链接,装载与库》一书
在这里插入图片描述
上图是ELF的两种视图,这里我们应该按照Execution View分析
我们可以使用readelf命令先分析一下kernel的组成
在这里插入图片描述
关键的信息有:

1.小端序,是可执行文件

2.系统架构是 80386

3.程序入口地址是0x10_0000(比加载kernel到内存的位置多了一个0!)

4.有三个程序头

再来看一下程序头表的内容
在这里插入图片描述
关键信息

1.text段的地址 0x10_0000,和程序的入口地址对应,这也是我们要跳转的地址。

2.data段的地址为0x11_0000

知道了这些,再来看代码
在这里插入图片描述
第一步,验证是否是有效的ELF,即开头是否是MAGIC NUMBER

然后把所有的程序段加载到对应的内存位置。

最后,跳转到程序入口(0x10_0000)执行代码

3.内存视图

1.ELF文件在0x10000处
在这里插入图片描述
2.kernel内存位置为0x100000
在这里插入图片描述
再综合一下之前的内存位置
在这里插入图片描述

4.总结

至此,boot部分就已经完成,下面就是真正的操作系统接手控制权了。作者对于ELF的理解也不是很深入,如果有错误,欢迎大家指出

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值