50

linux系统启动过程

 4 years ago
source link: https://www.tuicool.com/articles/rUfuiyV
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

BIOS

当我们给计算机加电的时候,计算机系统怎么知道该如何启动我们的操作系统呢?

首先计算机之中在主板上,有一个东西叫ROM(Read Only Memor),在ROM上固话了一些程序,被称为BIOS(基本输入输出系统),由于系统刚刚启动时处于实模式,关于什么是实模式,以及保护模式,可以看 这篇文章

实模式可操作的空间非常有限,只有2^20也就是1M的地址空间

Y7faqaN.jpg!web

在X86系统之中,将 1M 空间最上面的 0xF0000 到 0xFFFFF,一共64K映射给了ROM,当访问到这块地址的时候,就会访问到ROM。当加电的时候,系统加载ROM之中的BIOS之前,会完成一系列初始化工作

1. CS(代码段寄存器)置为0xFFFF

2. IP(指令指针寄存器)置为0x0000

所以对于第一条指令会指向0xFFFF+0x0000,也就是0xFFF0,处于ROM的地址空间内,这是一个JMP指令会调到ROM中执行初始化的工作,也就是开始了BIOS

BIOS会检查两件事情

1. 系统硬件是否完好

2. 建立中断向量表和中断服务程序

在BIOS阶段,也可以通过键盘的方式对BIOS发出指令,一旦通过键盘,就肯定会触发一个中断来让系统处理你的指令,所以第二个步骤是很有必要的。此时BIOS前期的工作就算完成

BootLoader

BIOS完成上述步骤后,就需要开始加载操作系统。一般的操作系统,例如在windows我们都会安装在C盘也就是硬盘上。在BIOS上我们也可以看到启动盘的选择。

启动盘的特点如下:

- 一般位于第一个扇区

- 占用512字节

- 以0xAA55结束

满足上述条件,可以称之为启动盘,并且在512字节内完成启动的相关代码。

启动盘里的代码是GRUB2(Grand Unified Bootloader Version2),定义的。也就是说BIOS执行了启动盘中由GRUB2定义好的一系列加载操作系统的步骤

可以通过 grub2-mkconfig -o /boot/grub2/grub.cfg 来定义系统启动执行的选项。这些代码

grub2定义的操作系统的步骤可以分为以下几步:

- boot.img

- diskboot.img

- lzma_decompress.img

- kernel.img

- 启动内核

boot.img

由boot.S编译而成,一共512字节,正好符合启动盘的第一个扇区的大小,所以会安装在这个第一扇区,通常这个扇区成为MBR(主引导记录扇区)

BIOS会将boot.img从硬盘加载到内存中的0x7c00来运行,因为只有512个字节,所以boot.img的唯一使命就是加载grub2的另一个镜像core.img

FjaQfqa.jpg!web

core.img由lzma_decompress.img,diskboot.img,kernel.img和一系列模块组成

boot.img会先加载core.img的第一个扇区,也就是diskboot.img

diskboot.img

由diskboot.S编译而成,任务是将core.img的其他部分一块加载到进来,显示解压它的下一步骤,lzma_decompress.img,再往下就是kernel.img,最后则是各个modules的映射,这里还不到linux的内核,所有都是grub的内核

lzma_decompress.img

由startup_raw.S编译而成,因为后续的kernel.img是经过压缩过后的,所以需要解压

同时它还需要完成从 实模式——>保护模式 的切换,为的是能在更大的寻址空间里,加载更多的东西

切换到保护模式,需要完成一系列动作

1、启动分段,将寄存器里的段寄存器变成段选择子(类似于索引),来指向某个段描述符(真正的段的起始地址),实现不同进程切换

2、启动分页

3、打开Gate A20,也就是第21根地址线的控制线,在8086模式下,一共只有20个地址线,总共可以访问1M的地址空间,所以保护模式需要启动第21根,来增大可以寻址的空间

kernel.img

由startup.S及一堆C文件编译而成,startup.S会调用grub_main(grub kernel的主函数)

主函数中

1. grub_load_config解析gurb.conf文件中的配置信息

2. 选定操作系统

3. 调用grub_menu_execute_entry,解析并执行选择的那一项

4. 其中选择的那一项可能会有很多指令,例如linux16,initrd等,都会执行对应的函数

5. 调用grub_command_execute,真正启动内核

总结

YNbq6rU.jpg!web


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK