操作系统实验Ucore:Bootasm启动(一)

此文章首发于我的博客:我的博客,博客上的排版更好一些…
首先,先放一张我画的Bootasm阶段(调用bootmain之前)的内存分布图
在这里插入图片描述
注:这个内存分布图只标识了大概位置,并没有考虑对齐
在此基础上,再来分析ucore的启动代码

1.启动地址

首先我们要知道第一条指令的地址在哪,当然,第一条指令指的时操作系统执行的指令。根据上图的描述,第一条指令的地址是0x7c00.
在这里插入图片描述
在makefile中,这一段程序指定了bootblock的入口函数为 start,其实地址为 0x7c00.使用gdb 调试可以很容易的验证我们的猜想。

这个0x7c00不是随意指定的,BIOS会磁盘的第一个扇区,也就是主引导扇区加载到0x7c00处,然后再将pc指向0x7c00.所以如果我们想要运行程序,就一定要先放在0x7c00处。

关于主引导扇区,可以看一下我之前的文章

2.执行指令

在这里插入图片描述
前两条指令是 cli 和 cld
cli 表示禁止中断,关于cld,我查到的资料是

cld使DF 复位,即是让DF=0,std使DF置位,即DF=1.这两个指令用于串操作指令中。通过执行cld或std指令可以控制方向标志DF,决定内存地址是增大(DF=0,向高地址增加)还是减小(DF=1,向地地址减小)。

在这里插入图片描述

然后就是 清零 ax 寄存器,并把ds,es,ss段寄存器赋值为0

此时我们还是在16位模式下的
在这里插入图片描述
这一段的作用是使能A20门.(标号是 set a20 我看了好久都没看出来…)关于A20门的作用,在ucore的文档上就有,大致是需要使能A20门才可以访问高于1MB的内存

3.A20门

我们具体来看一下是怎么使能A20门的,这部分的内容需要一个前置知识,就是CPU的端口.

这段代码里使用的0x60和0x64端口叫做 “8042” PS/2 Controller 是键盘的端口
文档在这里
在这里插入图片描述
0x64端口在读写时有着不同的意义,读时是状态寄存器,写时是命令寄存器
在这里插入图片描述

在向端口写入之前,我们要先确定端口是否可用。从0x64端口读出数据到al寄存器,如果第二个bit不是0,对应上图 Input buffer 的状态为 full ,就循环等待直到其为0。确认端口可用后,就向端口写入0xd1。
在这里插入图片描述
像0x64端口写入0xD1意味着我们要往0x60端口写数据。而且在写之前必须确认端口是空的。
最后,我们向0x60端口写入0xDF(第一个bit为1),开启A20门
在这里插入图片描述

4.加载全局描述符表寄存器GDTR

在这里插入图片描述
GDTR是一个48位的寄存器,其中高32位为基地址,低16位为段界限。这里把从gdtesc开始的6Byte载入GDTR中
在这里插入图片描述
gdt的描述在代码的最后,其内存位置(第一张图)也在高位。gdt里包含了三个段描述符,第一个是空描述符,第二个是代码段,第三个是数据段。

gdtesc中的低16位的十进制为23,代表gdt长度为(3*8 -1) = 23Byte,高32为是gdt的基地址。
在这里插入图片描述

在使用GDB调试的时候可以验证我们的猜想,光标部分就是三个段描述符,后面的 0x 7c540017 和 0x89550000是小段序,对应着 0x 0017 和 0x007c54. 前者对应段描述符的长度,后者对应起始地址。

加载完gdt后,将cr0的PE位置为1,进入保护模式

5.初始化保护模式

在这里插入图片描述
这里ljmp展开为 ljmp 0x8, protcseg

0x8 就是我们刚刚设置的 代码段 的段描述符,基址为0。因此会跳转到 protcseg标号处。

再接着就是把除了cs的所有段寄存器置为 0x10 , 即数据段的段描述符

6. Go to bootmain

在这里插入图片描述
最后一步,置ebp = 0 -> 栈底从0x7c00位置开始

置esp = start(0x7c00)-> 保存返回地址(当然不因该返回)

调用bootmain

由此也可以看出我们的栈内存空间是 0x0 到 0x7c00 的一段大概31KB的空间

完成了上述的几步之后,程序就跳转到了bootmain

7.结语:

零碎的看了好多次ucore,这次要从头开始认真做上面的文档有些看的不是很详细,有错误欢迎大家指出

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值