前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >操作系统的启动

操作系统的启动

原创
作者头像
hoikin-yiu
修改2020-08-25 16:39:15
1.3K0
修改2020-08-25 16:39:15
举报

操作系统的启动是个很令人好奇的话题,从按下计算机电源的那一刻,计算机从裸机开始呈现一个丰富的系统界面,这个从只有硬件逻辑到软件逻辑的过程是如何完成的?这里我们将从硬盘分区,三方协议,grub引导启动程序进行讲述,首先介绍硬盘MBR分区形式,然后介绍CPU,BIOS,系统的三方协议,讲述从CPU的硬件逻辑最终运行内核的软件逻辑的过程,最后介绍一下引导启动程序的发展,在grub这些引导启动程序中如何继续遵守三方协议。

1, MBR硬盘分区

MBR(Master Boot Record)即主引导记录分区表。它由三个部分组成:主引导记录,硬盘分区表和有效标志,共512字节,位于硬盘的0柱面、0磁头、1扇区。其中主引导记录占前446字节,硬盘分区表(DPT)占64字节,分区表里有4个表项,每个表项占16字节,最后是2字节的结束标志(固定为0x55AA)。在MBR分区中,第一个扇区的内容是十分关键的,它是主引导记录,如果操作系统需要按照MBR分区形式安装在这个硬盘中,那么需要在主引导记录里填入引导系统启动的代码。MBR分区在硬盘上的组织形式大致如下:

MBR分区示例
MBR分区示例

2, 三方协议

想要把操作系统启动起来,是需要多方按照一定的协议进行协作才能完成的,以Linux0.11,BIOS+MBR分区,Intel80x86CPU为例,首先电源加电后,主板会将BIOS从ROM里读取并放入内存RAM里,其在内存的位置是0xFE000~0xFFFF0,共计8KB,此时CPU加电后会进入16位实模式,通过硬件逻辑强行把自己的CS的值设置为0xF0000,IP的值设置为0xFFF0,这样CS:IP寻址就会指向内存的0xFFFF0,也就是BIOS的起始位置,那么BIOS程序就开始执行了,此时完成了CPU与BIOS的协同,彼此间的协议就是内存地址0xFFFF0!那么BIOS执行后,需要从硬盘或其他地方读取内核的代码,让内核执行起来,这如何做到呢?首先BIOS在开始执行时会把子机的中断向量表和BIOS数据放到内存的某个区域,中断向量表在0x00000~0x003FF,共计1KB,BIOS数据区在随后的0x00400~0x004FF,共计256B,建立好中断向量表以及其他操作后,BIOS会触发一个int0x19中断,CPU接收到这个中断后,会去内存的BIOS中断向量表里找到int0x19这个中断的中断服务程序(内存位置在0x0E6F2),这个中断服务程序的功能就是把磁盘里的第一个扇区(512B)读取到内存0x07C00(BOOTSEG)处,并开始执行它。此时内存第一次有了操作系统的代码,第一个扇区的内容其实就是linux/boot/bootsect.s的内容,其主要功能就是把第二批第三批代码加载到内存中规划好的位置。

bootsect.s的内存规划如下:

代码语言:c
复制
SETUPLEN = 4             ! nr of setup-sectors
BOOTSEG  = 0x07c0        ! original address of boot-sector
INITSEG  = 0x9000        ! we move boot here - out of the way
SETUPSEG = 0x9020        ! setup starts here
SYSSEG   = 0x1000        ! system loaded at 0x10000 (65536).
ENDSEG   = SYSSEG + SYSSIZE       ! where to stop loading

经过调整boosect自身在内存的位置之后,boosect开始把setup程序加载到内存中,此时使用的另一个中断向量int0x13,此中断向量可以指定扇区和内存位置,将指定扇区的内容读取的指定的内存位置。在bootsect中,读取的是从第二个扇区开始的4个扇区,加载到0x90200(SETUPSEG)处,这些内容对应linux/boot/setup.s这个文件。加载进来后,setup会再次调整内存规划,然后会使用int0x13中断向量继续加载240个扇区的内容,也就是system模块。setup还会做一些设置,例如关中断,设置中断描述符表和全局描述符表,打开A20实现32位寻址,对编程中断控制器8259A进行重编程,建立保护模式下的中断机制等等,为内核main函数的调用做准备。此时内存的视图如下:

linux0.11启动阶段内存视图
linux0.11启动阶段内存视图

所以,我们可以知道,当BIOS运行后,会通过int0x19中断读取第一扇区的内容,BIOS并不管这个扇区里是否有内容。如果我们系统安装在硬盘上,就得保证第一扇区是我们的bootsect,这样才可以通过int0x13读取其他扇区的setup和system,从而最终完成内核的启动。所以这个第一扇区是至关重要的,是BIOS与系统的协议。

3, grub

经过多年的发展,引导程序已经由最初像Linux0.11的bootsect.s,setup.s等发展为grub,grub2之类的启动引导程序,第一扇区(主引导记录)也从bootsect.s变成了stage1,boot.img这些形式的内容,这类引导程序可以引导多个操作系统,多种操作系统的启动,拥有配置文件和简单的命令行界面,功能变得十分强大。不过grub跟最初的引导程序一样,也是遵循BIOS+MBR的规则的。gurb对系统的引导也是分为三个阶段,步骤1(stage1)的内容存放在主引导记录里,其功能主要是加载步骤1.5(stage1.5)的内容,也就是grub到内存中,步骤1.5会加载步骤2的内容,步骤2启动后,将会呈现一个选择启动的操作系统的界面。grub2是grub的升级版,在硬盘分区的内容与grub类似,只是stage1变成了boot.img,stage1.5变成core.img。

grub与gurb2在磁盘的分布
grub与gurb2在磁盘的分布

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档