Linux系统启动流程

CentOS6系统启动流程

  操作系统(OS)也是一个程序,如果在硬件通电后让这个特殊的程序运行起来,以及这个特殊的程序在启动过程中做了什么,如下图:
《Linux系统启动流程》

  从图中可知,系统启动(不仅仅是Linux系统)大致可分为几个主要过程:硬件初始化–>找到并加载操作系统的内核–>内核初始化–>操作系统运行环境初始化–>登录初始化–>登录成功后的用户初始化(包含图形界面初始化或shell的初始化)–>最终用户成功进入
操作系统并开始使用操作系统。

下面以CentOS6系统进入命令行为例简单描述一下上面的几个主要过程。

1.按下电源通电。主板通电后,CPU开始工作,它执行固定地址处的一段非常小的硬编码程序:BIOS,于是BIOS掌握了CPU控制权。

2.BIOS程序会进行硬件的上电自检(Power-On Self-Test,POST)以确认有哪些硬件以及这些硬件是否故障。对于我们要探索的操作系统启动流程来说,最重要的是会根据检测到磁盘顺序(除了磁盘,也可以是其它硬件设备,比如U盘、光盘、网卡等),按顺序找到这些磁盘上正确的MBR,于是MBR开始掌握CPU控制权。

3.MBR是引导系统内核启动的第一段代码,它的位置固定处于磁盘的第一个扇区位置处(如果不固定,就不知道怎么找到MBR)。引导内核启动的代码段称为Boot Loader,除MBR外,还需要通过其它引导系统的代码段来一步步引导启动内核,所以要引导一个内核的启动,需要跳转并执行多段BootLoader。根据使用的启动管理工具(如LILIO、GRUB、GRUB2等)不同,这一段段的引导代码段称呼和存放位置都不一样,但第一个引导内核启动的代码段一定称为MBR,也一定处于磁盘的第一个扇区位置,所以MBR才称为主引导记录(Master Boot Record)。

4.当找到内核映像后,将内核映像装载到内存中并解压(如果被压缩的话),内核开始掌握CPU控制权并运行起来,期间内核会做很多工作,包括内核的初始化、挂载真正的根目录并从临时根目录切换到真正的根目录、启动一些重要的进程,例如idle、进程调度器、init进程等。然后开始执行用户空间的第一个进程:init进程,于是init进程掌握了CPU的控制权,也从此开始进入用户空间。

5.init进程开始运行后就表示操作系统真正已经启动成功了,但它仍然需要做系统级别的初始化,比如设置主机名、设置硬件参数、加载硬件驱动、挂载/etc/fstab中的一些文件系统等等。系统级别的运行环境一切初始化完成后,于是提供用户登录的界面,即init启动getty类的进程。

6.getty类的进程启动后,将打开一个终端,并提示用户输入用户名,然后启动一个login进程让用户输入密码并验证密码,密码验证通过后再审覈用户是否有权登录,如果允许登录,将根据/etc/passwd中的配置启动该用户对应的shell进程,例如bash进程。

7.shell进程启动后读取该shell对应的配置文件,并按照登录式、交互式的shell运行模式进行初始化,初始化完成后将进入登录式、交互式的shell,也就是命令行下。

8.至此,用户可以通过shell命令行来使用操作系统。

CentOS7系统启动流程

CentOS7的启动与CentOS6启动不同之处有两大点:
1)内核引导阶段,CentOS7默认使用grub2引导,而CentOS6默认使用传统的grub引导。
2)系统环境初始化和后面的过程。内核初始化完成后,启动PID=1的过程,而CentOS7中这个进程是systemd,它和CentOS6中的init进程的初始化方式大不相同。

systemd特性:
1)系统初始化时实现服务并行启动;
2)按需启动守护进程;
3)自动化的服务依赖关系管理;
4)同时采用socket式与D-Bus总线式激活服务;
5)系统状态快照。

以下简述CentOS7的启动流程,详细内容参考:man bootup帮助手册。
1)UEFI或BIOS初始化,运行POST开机自检;
2)选择启动设备;
3)引导内核,做部分内核初始化工作,加载initramfs;
4)启动systemd进程,systemd进程此时工作在initramfs环境下;
5)systemd执行initrd.target所有单元,包括挂载/etc/fstab、从ramdisk的虚根文件系统切换到真正的根文件系统;
6)systemd执行默认target配置,其配置文件为/etc/systemd/system/default.target;
7)systemd执行sysinit.target初始化系统及basic.target准备操作系统;
8)systemd启动multi-user.target下的本机与服务器服务;
9)systemd执行multi-user.target下的/etc/rc.d/rc.local;
10)systemd执行multi-user.target下的getty.target让用户登录;
11)启动shell进程并初始化,最终进入命令行;

  上面的过程中最需要关注的便是大大提前了systemd的工作:在内核初始化阶段就参与了剩下的工作。等到systemd完成了根文件系统的切换后,将正式进入操作系统的初始化过程,这时将进入步骤6),即根据默认target配置文件default.targe选择默认的“运行级别”。

点赞