linux 启动流程
POST BIOS(boot sequence) 所选择的启动设备次序的MBR中是否有引导程序, ----> MBR(bootloader) 提供内核列表 ------->加载选定的Kernel,initrd(内存模拟的磁盘设备需要缓存),initramfs(缓存) ---->获取到根文件系统并挂载,运行init
bootloadler开始以后的挂载流程
1、当系统读取bootloader,挂载内核分区的时候,不识别更高级的磁盘分区上,只能放在基本磁盘分区,而且只支持read1,所以内核和根不在同一个磁盘分区上,我们通常把内核所在的基本磁盘分区挂载到boot分区上。
2、最终bootloader在启动的时候是在临时挂载的 / 下找 vminuz
3、为了节约磁盘空间vmlinuz是被压缩的,节约空间和保证IO速度。在使用的时候内核需要解压,此时vmlinuz被分为2段,一段是没有压缩(解压算法),另一端是压缩的。
解压后 bootloader读取initramfs,的控制权完全交给kernel,内核完成自身初始化,加载磁盘完成后启动init
问题1:/lib/modules在跟文件系统中,kernel如何挂载?不挂载又怎么能找到这个硬盘的驱动程序?
/lib/modules/中是linux所需要的所有模块存放位置,但是kernel现在不知道我们的设备硬件是什么,kernel不可能将所有的模块都放在内核中,因为硬件设备以及功能模块太多了。所以就放到了/lib/modules。但是/lib/modules又是在跟文件系统中。那此时kernel如何能找到硬盘的驱动模块完成并加载呢?因为此时的模块就是在根文件系统上,我们需要先挂载他才能找到所有的模块。这个情况就是为什么要在boot分区中还要放置一个initrd文件的原因了。这个就是启动时加载Kernel后挂载的临时根文件系统。
问题2:又是谁探测到了你的硬盘的型号,并把对应的驱动模块放置在initramfs文件中提供给bootloader呢?
是安装操作系统时,安装程序在安装操作系统时可以探测到你的硬盘是什么设备,需要什么启动程序,做成initramfs文件放到了 bootloader可以读取到的根文件系统中,这样kernel就可以通过这个文件加载根文件系统,而后就可以读取/lib/modules/ 加载所有的其他需要的模块了
就是这个文件,所以有可能都安装了同样的操作系统,但是硬盘的驱动不同。导致了硬盘互换也不能启动的原因。
initrd是个文件系统,帮助kernel完成初始化。内核要将其挂载,以这个为根,挂载后在这里加载真正根文件系统的驱动模块,加载后initrd中有个程序运行后可以替换跟文件系统,将真正的根文件系统替换initrd,替换完以后这个应用程序由谁终止,自身终止就是系统启动的第0个进程。之后就是要访问/sbin/init
/sbin/init: 功能
/etc/inittab
/etc/rc.d/rc.sysinit脚本
init特性:
Centos 5 init: SystemV格式:启动顺序是串行化,初始化程序一个一个执行
Centos 6 init: Upstart:程序依然有依赖,但是不用等待所依赖的程序完成初始化完成(启动初始化程序通过dbus相互通信),和System V兼容性不太好。
Centos 7 : SystemD,和SysV兼容。并且参考OS X 中并行初始化的过程
启动应用程序:将应用程序定义到启动级别中
0:关机
1:单用户模式
2:多用户模式,不支持NFS文进系统
3:完全多用户模式
4:预留级别
5:完全多用户模式:图形模式
6:重启