上一篇博客按下计算机电源键的一刻发生了什么(1)?我们说到开始加载linux内核文件,系统开始正式启动,回顾一下都大体经历了哪几个步骤:
1:通电之后BIOS从CMOS读取硬件参数信息,接着BIOS自检,找到我们设置的启动盘。
2:开始读取启动盘“0“磁道“1“扇区的MBR信息,执行boot loader程序。
3:根据boot loader找到我们内核文件的位置,开始加载内核文件。
好,我们接下来就继续从加载到内核文件开始说。
当我们的操作系统将内核文件加载并解压到内存中之后,根据内核的功能,它还会自己再次检测各种硬件是否正常,并不一定会使用BIOS检测到的硬件信息,我们的内核文件一般为/boot/vmlinuz.我们如果将硬件,操作系统,应用分为三个层次,如图所示:
内核有以下功能:进程调度,进程间通信,内存管理,虚拟文件系统,网络接口,它还会驱动提供统一的接口,一般来说,我们的内核是被模块化的,因此目前USB,STAT,SCSI等磁盘设备的驱动程序通常都是以模块的方式存在的。这里必须要讲到虚拟文件系统的功能。
虚拟文件系统:一般的文件名为/boot/initrd,这个文件的特点是它可以被boot loader加载到内存中,然后这个文件会被解压缩并且在内存中仿真成一个根目录,且这个仿真在内存中的文件系统能够提供一个可执行程序,通过该程序来加载启动过程中所最需要的内核模块,即一些驱动程序。
所以此时我们的boot loader实际上加载两个东西,一个是kernel文件,一个是/boot/initrd,然后在内存中让它initrd解压缩成为根目录,kernel就能够借此加载适当的驱动程序,最终释放虚拟文件系统,并挂载真正的根目录文件系统。在我们的启动过程中,这样的情况一般是当我们的根目录在特殊的磁盘接口(USB,STAT)等等,或者是文件系统比较特殊(LVM,RAID),才会需要initrd。如果我们的linux安装在IDE接口的磁盘上,并且使用默认的ext2/ext3系统,那么不需要initrd也是可以进入linux的。
在我们的内核加载完成之后,就要开始执行系统的第一个程序:/sbin/init
(虽然现在更新为systemd,但是只是它们的管理方式不同,systemd用target来管理。在/etc/systemd/system下)
我们看到好多链接,例如default.target就是我们默认的启动level,图中的graphical.target就是我们6层启动级别的第5层图形启动。
接下来init进程执行rc.sysinit,在设定了运行等级后,Linux系统执行的第一个用户层文件就是/etc/rc.d/rc.sysinit脚本程序,它做的工作非常多,包括设定PATH、设定网络配置(/etc/sysconfig/network-scripts/),启动swap分区、设定/proc等等。
接下来再根据运行级别的不同,系统会运行rc0.d到rc6.d中的相应的脚本程序,来完成相应的初始化工作和启动相应的服务。
然后再是依据/etc/modules.conf文件或/etc/modules.d目录下的文件来装载内核模块,init执行run-level的各种Scripts,启动服务.
最后init执行/etc/rc.d/rc.local加载用户自己设定的一些参数,具体参照自己个人设定。
执行/bin/login程序,进入登录状态