Linux启动过程

152 阅读4分钟

linux系统层次 image.png

启动过程

每个平台的细节不同,但是整体来说,下面的步骤代表了启动的过程。

1、当计算机启动时,BIOS加电自检(POST),并对硬件进行检测和初始化,这是因为操作系统的启动过程可能会依赖于磁盘的访问、屏幕、键盘等。

2、接下来,启动磁盘的第一个扇区,即主引导记录(MBR),被读到一个固定的内存区域并执行。这个分区中含有一个很小的程序(只有512字节),这个程序从启动设备中,比如SATA磁盘或SCSI磁盘,调入一个名为boot的独立程序,boot程序将自身复制到高地址的内存当中从而为操作系统释放低地址的内存。

3、复制完成后,boot程序读取启动设备的根目录。为了达到这个目的,boot程序必须能够理解文件系统和目录格式,这个工作通常由引导程序,如GRUB(多系统启动管理器),来完成。其他流行的引导程序,如Intel的LILO,不依赖于任何特定的文件系统,想法,它们需要一个块映射图和低层地址,它们描述了物理扇区,磁头和磁道,可以帮助找到相应的需要被加载的扇区。

4、然后,biit程序读入操作系统内核,并把控制交给内核。从这里开始boot程序完成了它的任务,系统内核开始运行。

5、内核的启动代码是用汇编语言写成的,具有较高的机器依赖性,主要的工作内容包括创建内核堆栈、识别CPU类型、计算可用内存、禁止中断、启用内存管理单元,然后掉用C语言写成的main函数开始执行操作系统的主要部分。

6、C语言代码也有相当多的初始化工作要做,但是这些工作更逻辑化(而不是物理化),C语言代码开始的时候会分配一个消息缓存区来帮助调试启动出现的问题,随着初始化工作的进行,信息被写入消息缓存区,这些信息与当前正在发生的事件相关,所以,如果出现启动失败的情况,这些信息可以通过一个特殊的诊断程序调试出来。我们可以把它当成是操作系统的“飞行信息记录器”(即空难发生后,侦测员会寻找的黑盒子)。

7、接下来,内核数据结构得到分配,大部分内核数据结构的大小是固定的,但是一少部分,如页面缓存和特殊的表结构,依赖于可用内存的大小。

8、从这里开始,系统进行自动配置,使用描述何种设备可能存在配置文件,系统开始探测哪些设备是确实存在的,如果一个被探测的设备给出了响应,这个设备就会加入到已连接的设备表中。如果它没有响应,就假设它未连接或直接忽略掉它。不同于传统的UNIX版本,linux系统的设备驱动程序不需要被静态连接至内核中,他们可以被动态加载。

9、一旦所有的硬件都配置好了,接下来要做的事情就是细心地手动运行进程0,建立它的堆栈,运行它。进程0继续进行初始化,做如下的工作;配置实时时钟,挂载根文件系统,创建ini进程(进程1)和页面守护进程(进程2)

10、init进程检测它的标志已确定它应该为单用户还是多用户服务,前一种情况,它调用fork函数创建一个shell进程,并且等待这个进程结束。后一种情况,它调用fork函数创建一个运行系统初始化的shell脚本(即/etc/rc)的进程,这个检查可以进行文件系统的一致性检测,挂载附加文件系统,开启守护进程等。然后这个进程从/etc/ttys中读取数据,其中/etc/ttys列出了所有的终端和它们的属性。对于每一个启动的终端,这个进程调用fork函数创建一个自身的副本,进行内部处理并运行一个名为getty的程序。

11、getty程序为每条连线设置传输速率和其他属性(比如,有可能是一个调制解调器),然后在终端的屏幕上输出:login:

顺便分享一些作者有趣的比喻

770ac8f6a61c5ecfbce54edc449a9d5.png

303bfc1e531d120325ba93f6a6e528c.png

89775a62a07b3d765fb0d593e745566.png

文章来源:现代操作系统第4版