[操作系统] 启动

启动

一、通电

由于内存是随机存储器(Random access memory,RAM),属于易失性存储器,未通电时,RAM中不会有任何内容,因此刚一通电,RAM不可能有任何实际信息。计算机硬件厂商在只读存储器(Read-only memory,ROM)中开辟了一块空间,固化了一段代码,这段ROM被称为BIOS(basic input/output system,基本输入输出系统),其中放置的代码是对基本硬件的测试代码,IBM PC中,这段代码的起始地址就在 0xFFFF0。

计算机刚一通电,CS的初始值就被设置成 0xFFFF,IP的初始值设置成 0x0000,计算机首先工作在实模式下,实模式下取出指令地址的方式是将CS中的值左移四位,再加上IP中的值:

P C = C S < < 4 + I P = 0 x F F F F 0 PC=CS<<4+IP=0xFFFF0 PC=CS<<4+IP=0xFFFF0

即执行ROM中固化的那段代码,测试各种硬件是否正常,如果出现异常,则停止启动,并控制喇叭发声报错。(平常内存条松动,电脑开不了机时,发出的滴滴声)

如果硬件测试正常,利用BIOS的输入功能,将启动磁盘中的第一个扇区的内容(bootsect.s)读入内存 0x7C00 地址处,并设置CS=0x07C0,IP=0x0000,即将PC指针指向bootsect.s 的第一条指令处,开始执行 bootsect.s 的内容。
在这里插入图片描述

二、bootsect.s

1、bootsect.s 代码整体移动位置

将内存中 0x7C00 处的 512 个字节(正好就是全部 bootsect.s)移动到内存地址 0x90000 开始的一段内存中
在这里插入图片描述

2、读入setup.s

执行指令 “int 0x13”,调用0x13号中断,这是BIOS中断中的读写磁盘的一个中断,从磁盘中,将后续4个扇区(bootsect.s 在第一个扇区)的内容读入内存 0x90200处。

0 x 90200 − 0 x 90000 = 0 x 200 0x90200-0x90000=0x200 0x902000x90000=0x200
差了0x200,十六进制下,正好是十进制的512,由于是内存地址,每1相当于一个字节,正好是512个字节

也就是说,读入的 setup.s 正好接在 bootsect.s 的末尾处

在这里插入图片描述

3、在屏幕上输出 “Loading System…”

调用BIOS中断 int 0x10,该中断的作用是在屏幕上输出信息

4、读入system

从启动磁盘中的第六个扇区开始,读入长度为 SYSSIZE 的操作系统 system 模块,放置在内存 0x10000 处

在这里插入图片描述

5、PC指针设置为 0x90200

bootsect.s 的最后,将PC指针设置成 0x90200,开始执行 setup.s 的第一条指令,bootsect.s 的任务结束
在这里插入图片描述

二、setup.s

1、获取初始化所需的基本参数

以内存为例,setup.s 调用 0x15号BIOS中断,获取扩展内存的大小,单位是KB,并将内存尺寸存放在地址 0x90000 处,将来系统初始化时,需要来到 0x90000 处读取这个值,用于初始化内存管理

2、将内存中的system模块,移动到0x0地址处

在这里插入图片描述
这一步会使得BIOS中断向量表(放置在0地址处)被覆盖,因此从这里开始,BIOS中断将无法使用

3、创建临时GDT表

创建并设置一个临时的GDT表,暂时只用于一步内存跳转 “jmpi 0,8” 使指令跳转到 0x0地址处

4、启动保护模式

在这之前,PC的寻址模式还是实模式,PC=CS<<4+IP

setup.s 将A20号地址线选通,并且将寄存器CR0最后一位设置为1,一旦完成这两项设置,内存寻址方式会切换到另外一套电路——保护模式

在保护模式下,PC指针通过段基址+段内偏移的方式完成寻址,而段基址通过CS寄存器内的值,查询GDT表(全局描述符)得到,保护模式下的PC寻址方式:

P C = G D T [ C S ] + E I P PC=GDT[CS]+EIP PC=GDT[CS]+EIP

5、jmpi 0,8

在保护模式下,执行 jmpi 0,8 ,PC=GDT[8]+0=0,PC指针跳转到 0x0地址处,setup.s 的任务完成,开始执行 system 模块中的第一段代码 head.s
在这里插入图片描述

三、system——head.s

1、设置中断表(interrupt descriptor table,IDT)

因为system被从0x10000处挪到0x0处,将原本放置在0x0处的BIOS中断向量表覆盖了,BIOS中断将不再能使用,操作系统需要接管中断。在这一步中,IDT表创建,但全部表项初始化成0,即所有的中断暂时不可用,要等到后面给每个模块(如时钟)初始化时,才会设置相应的中断处理程序的入口地址到各个表项中

2、设置GDT表

setup.s 中创建的GDT表是临时的,只是用于在保护模式下将PC指针跳转到0x0地址处,这里需要重新创建 GDT表

3、设置页表

保护模式下,GDT[CS]+EIP得到的是32位的虚拟地址,还需要根据段页内存管理,去页表中找到跟物理地址的映射,详情在《内存》中。
https://blog.csdn.net/weixin_44179561/article/details/127154863

4、head.s 的最后一段代码,使PC指针跳转到操作系统的初始化代码处

四、操作系统初始化

初始化内存mem_map,初始化一些重要的数据结构

五、进入内核态,创建进程,进入shell(即命令窗口)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值