《自己动手写操作系统》——启动流程


本文接前文—— 《自己动手写操作系统》——制作一个简单的操作系统-CSDN博客内容,回答为什么机器开机后会执行这段汇编代码,这段代码有什么特殊之处?

背景知识

8086CPU

  • 处理器是16位,地址总线是20位,访存范围是1MB。

CS和IP寄存器

参考CS和IP寄存器的作用及执行分析_cs寄存器和ip寄存器的作用-CSDN博客得到这几点关键结论:

  • 任何时刻,8086CPU都会将CS:IP指向的指令作为下一条需要取出的执行指令
  • 8086CPU中的计算公式为 (CS << 4)|IP, 即CS左移4位,然后再加上IP

BIOS

  • CPU加电之后,硬件会把一个ROM芯片映射到地址空间0xF0000~0xFFFFF上。同时,会把CS寄存器的值改为0xFFFF,其余寄存器的值全部清零,因此此时CS:IP=0xFFFF:0x0000=0xFFFF0,即下一条即将执行的指令位置。而0xFFFF0~0xFFFFF之间其实只有16B的空间,这里只是一条跳转指令,跳转到BIOS真正的入口地址:
jmp far f000:e05b #- 这条指令会将CS设为0xf000,将IP设为0xe05b,对应的指令地址是0xfe05b
  • CPU随后开支执行BIOS上的代码,主要是是硬件输入输出设备相关的检查,以及建立一个最初的中断向量表(位于0x00000~0x003FF之间);
  • BIOS 代码最后阶段的工作,就是检查启动盘上的 mbr 分区,所谓 mbr 分区就是磁盘上的第一个 512B 内容,又叫引导分区;BIOS 会对这 512B 做一个检查:它的最后2个字节必须是两个 magic number:0x55 和 0xaa,否则它就不是一个合法的启动盘;
  • 检查通过后,BIOS 将这 512B 加载到内存0x07C00 ~0x07E00之间,然后指令跳转到0x07C00开始执行,至此 BIOS 退出舞台;

系统启动

启动image是由 bootsect、setup 和 system 三个顺序合并形成的;bootsect 是由 bootsect.s 汇编产生的;setup是由 setup.s 汇编产生的;system 是由进程模块、内存模块、设备驱动、初始化模块等部分组成的。

bootsect.s

这个汇编程序编译之后大小严格为512B,且满足最后两个字节是0x55 和 0xaa,它主要完成以下几件事情:

  • 将引导磁盘上的第2~5这四个扇区构成的 setup 模块读入到了内存的0x90200 处;
  • 将引导磁盘上的第6个扇区开始读取长度为 SYSSIZE 的操作系统 system 模块,并将其存放到内存的 0x10000 处。

由此可见,这段代码的作用是将setup和system模块加载到内存中。

setup.s

setup.s 的主要任务包括:(1)获取一些硬件参数,包括内存大小、磁盘信息、硬件信息等;(2)在实模式下先完成 GDT 表的形成以及初始化;(3)在实模式下将整个 system 模块拖动到 0x0 地址处;(4)进入保护模式。

进入保护模式之后,就允许访问1MB之后的扩展内存,供上层应用使用。而1MB就留给操作系统,其中:

  • 0x00000~0x90000存放sysetem模块;
  • 0x90000~0x100000存放重要参数。
    在这里插入图片描述

head.s

head.s是在32保护模式下执行的代码,主要任务包括:

  • 设置中断表 IDT
  • 设置 GDT 表
  • 设置页表
  • 跳到操作系统的初始化代码

main.c

main.c的主要任务是读取各种参数完成初始化,并启动一个shell终端,并响应shell命令。至此,操作系统相当于启动完毕。

实模式和保护模式

实模式

早期CPU时期,地址总线是20位,8个16位通用寄存器和4个16位段寄存器,通过物理地址 = 段基址<<4 + 段内偏移这种方式计算物理地址,访问范围为1MB。

保护模式

后来的CPU,地址总线是32位,寄存器也是32位,因此内存访问范围为4GB,但是依然采用段地址:段内偏移的方式表示地址。

  1. 首先从gdtr寄存器(48位寄存器,保存了GDT基址和GDT长度)拿到GDT的基址,从段寄存器中拿到索引(16位);
  2. 结合基址和索引,从GDT中拿到对应的描述符(每个描述符占据8个字节,存储了段基址、段界限和段属性);
  3. 从GDT条目中获取段基址base(32位);
  4. 结合寄存器中的偏移地址offset(32位),可以计算出线性地址线形地址 = 段基址 + 段内偏移
  5. 通过MMU和分页机制,实现由线性地址转换为物理地址。

内存布局

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值