【linux】linux启动过程

1.POST开机自检

linux开机加电后,系统开始开机自检,该过程主要对计算机各种硬件设备进行检测,如CPU、内存、主板、硬盘、CMOS芯片等,如果出现致命故障则停机,并且由于初始化过程还没完成,所以不会出现任何提示信号;如果出现一般故障则会发出声音等提示信号,等待故障清除;若未出现故障,加电自检完成。

2.加载BIOS

开机自检完成后,CPU首先读取位于CMOS中的BIOS程序,按照BIOS中设定的启动次序(Boot Sequence)逐一查找可启动设备,找到可启动的设备后,去该设备的第一个扇区中读取主引导目录(MBR),那么MBR是什么?它又有什么作用?

MBR存在于可启动磁盘的0磁道0扇区,占用512字节,它主要用来告诉计算机从选定的可启动设备的哪个分区来加载引导加载程序(Boot loader),MBR中存在如下内容:

  1. Boot Loader 占用446字节,存储有操作系统(OS)相关信息,如操作系统名称,操作系统内核位置等,它的主要功能是加载内核到内存中运行。
  2. Partition Table 分区表,占用64字节,每个主分区占用16字节(这就是为什么一块硬盘只能有4个主分区)
  3. 分区表有效性标记占用2字节 ,CPU将MBR读取至内存,运行GRUB(Boot Loader常用的有GRUB和LILO两种,现在常用的是GRUB),GRUB会把内核加载到内存去执行。
# ll /boot
...
-rwxr-xr-x. 1 root root  6762688 Mar 31  2020 vmlinuz-3.10.0-1127.el7.x86_64
initramfs-2.6.32-642.el6.x86_64.img

可以看出,内核文件存在于/boot/目录下,3.10.0-1127是内核版本号,el7是操作系统版本。但是在GRUB加载内核时,连/还没有被加载,它是怎么在磁盘上找到内核的?加载内核不通过根文件系统,而是直接访问磁盘分区,因为此时内核还没有启动,不存在文件系统。看一下grub配置文件(centos在/boot/grub2/grub.cfg):

在/boot/grub/grub.conf中可以看到root(hd0,0),表示内核文件和加载根文件系统的驱动程序的位置在第一块硬盘的第一个分区下,在此分区中的目录/boot/,驱动程序可在initramfs-2.6.32-642.el6.x86_64.img中加载。

这个阶段总结起来就是通过引导程序找到内核并加载到内存中。

3.加载内核,初始化initrd

将内核加载至内存之后,内核会进行接下来的工作:探测硬件->加载驱动->挂载根文件系统(initrd)->切换至根文件系统(rootfs)->运行/sbin/init完成初始化工作。

此时会出现一个问题,要访问根文件系统,需要先挂载,而挂载根文件系统需要先加载根文件系统的驱动程序,为了解决这个问题,GRUB在加载内核至内存中时,也把initrd加载内核中并运行,而initrd有什么作用呢?

initrd镜像文件也存在于/boot中,将其展开后:

bin  dev  etc  init  lib  lib64  proc  root  run  sbin  shutdown  sys  sysroot  tmp  usr  var

可见它和我们常见的根目录的文件很像,里面有bin、lib、lib64、sys、var、etc、sysroot、 dev、proc、tmp等目录,它的功能现在内存中建立一个虚拟的根文件系统,然后再加载根文件系统(rootfs)的驱动,然后以读写的方式挂载,就是真正的根文件系统。

4.运行/sbin/init,运行系统初始化

挂载根文件系统的其中一个目的就是运行init进程需要一个文件系统作为载体,在完成根文件系统的挂载之后,会执行第一个进程init,init首先运行/etc/init/下的脚本。

init主要完成的工作是:

  • 获得网络环境
  • 挂载设备
  • 开机启动画面Plymouth(取替了过往的 RHGB)
  • 判断是否启用SELinux
  • 显示于开机过程中的欢迎画面
  • 初始化硬件
  • 用户自定义模块的加载
  • 配置内核的参数
  • 设置主机名
  • 同步存储器
  • 设备映射器及相关的初始化
  • 初始化软件磁盘阵列(RAID)
  • 初始化 LVM 的文件系统功能
  • 检验磁盘文件系统(fsck)
  • 设置磁盘配额(quota)
  • 重新以可读写模式挂载系统磁盘
  • 更新quota(非必要)
  • 启动系统虚拟随机数生成器
  • 配置机器(非必要)
  • 清除开机过程当中的临时文件
  • 创建ICE目录
  • 启动交换分区(swap)
  • 将开机信息写入/var/log/dmesg文件中

等。然后根据/etc/inittab中设定的系统运行默认级别,然后按照对应的级别x,运行/etc/rc.d/rcx脚本.....

在较新的linux内核版本中,使用了systemd替换调了init进程作为第一个进程启动。

5.打印登录提示信息

系统初始化完成后,init给出用户登录提示符(login)或者图形化登录界面,用户输入用户和密码登陆后,系统会为用户分配一个用户ID(uid)和组ID(gid),这两个ID是用户的身份标识,用于检测用户运行程序时的身份验证。登录成功后,整个系统启动流程运行完毕!

参考:https://cloud.tencent.com/developer/article/1114481