第一步:BIOS启动
服务器接通电源后,第一步是进行BIOS的启动。BIOS, Basic Input/Output System, 即基本输入输出系统,是一个基础的、简单的操作系统,存在于服务器的BIOS芯片中,主要有服务器硬件自检、CMOS设置、引导操作系统启动、提供硬件I/O、硬件中断等主要功能。
当服务器上电后,BIOS首先进行一些系统设备检查和初始化,包括对CPU、内存时钟、硬盘(HDD/SDD)的校验和挂载, 搜索主引导记录(Master Boot Record, MBR)。
BIOS会加载并执行在主引导记录找到的引导程序(Boot loader)。
MBR通常存在与硬盘上,也可能在U盘上,或者CD-ROM的光盘上。
BIOS也支持从网络引导,如PXE引导的功能,即从远端的服务器取回引导程序并加载。
BIOS找到Boot loader后,就会将其加载进内存,并将系统交给Boot loader控制。
说明:当前主流的服务器已经采用UEFI的引导方式,相比BIOS,UEFI有更规范的标准,提供包括安全在内的更多的功能。
第二步:MBR
MBR(Master Boot Record,主引导记录),是采样MBR分区格式的硬盘的第一扇区,即C/H/S地址的0柱面0磁头1扇区,对应LBA 0,也叫MBR扇区,包括引导程序、分区表、分隔标识三部分。
MBR是可引导磁盘(Bootable disk)的第一个扇区,在Linux下通常是/dev/hda
或者/dev/sda
设备。对Linux系统而言,MBR中的引导程序通常是GRUB, 一种多重操作系统启动管理器。另外一种更古老的引导程序是LILO, 服务器上已经很少使用。
说明:GPT, Globally Unique Identifier Partition Table ,全局唯一标识分区表,是一种更的硬盘分区格式,相比MBR, 支持更多大容量的硬盘,更多的分区。
第三步:GRUB
GRUB有时候也称为GNU GRUB, 是GNU GRand Unified Bootloader的缩写,是一种Linux系统上典型的引导程序。
GRUB启动图像(GRUB splash screen)通常是用户启动服务器后看到的第一个图像(在这之前也可能有BIOS的显示信息),它有一个简单的选择菜单列出一些启动选项。如果装有多个操作系统,可以通过键盘选择需要引导的操作系统,否则会在一定的超时时间后(通常是几秒)引导默认的系统内核镜像。
通常在Linux系统中,可以在如下路径找到GRUB的配置文件:/boot/grub/grub.conf
或者/etc/grub.conf
。一个配置文件例子:
#boot=/dev/sda default=0 timeout=5 splashimage=(hd0,0)/boot/grub/splash.xpm.gz hiddenmenu title CentOS (2.6.18-194.el5PAE) root (hd0,0) kernel /boot/vmlinuz-2.6.18-194.el5PAE ro root=LABEL=/ initrd /boot/initrd-2.6.18-194.el5PAE.img
GRUB引导程序可以分成两个阶段:
第一个阶段保存在MBR中,即MBR的引导程序,完成基本的必要的硬件设备初始化,将GRUB的第二阶段程序加载到内存空间中,配置堆栈后跳转到第二阶段程序入口。
第二阶段,初始化本阶段用到的硬件设备,检测系统内存映射,将Linux内核镜像和根文件系统镜像镜像从磁盘加载到内存中,安装配置文件读取内核启动参数并启动内核。
第四步:内核
内核(Kernel)通常是指包括Linux在内的任何操作系统的核心部分。它完全控制服务器系统上的所有设备。
在启动阶段,由GRUB选择的内核会根据grub.conf
先挂载(mount)根文件系统(root file system)。然后执行其中的/sbin/init/
程序,init程序总是内核启动的第一个进程。init
进程的PID是1,可以通过进程的进程ID(PID)
来确认该进程。
然后,内核会使用初始内存镜像盘(Initial RAM DISK, initrd)来建立一个临时的根文件系统,直到从硬盘上(或别的地方)建立的真正的文件系统被挂载为止。
第五步:Init
在这一步,服务器系统会执行运行级别(runlevel)
程序。它会寻找初始化文件(通常在/et/inittab
)来决定Linux的运行级别。运行级别可以理解为系统提供的服务集合的一个子集。这些服务的配置文件通常存放在etc/init.d/
目录下,不同的运行级别选择这些服务并在/etc/rcN.d目录建立连接,确定运行级别后,就执行相应运行级别rcN.d
目录下的所有服务。这些服务配置文件按照K+nn+servicename
或S+nn+servicename
的规范命名,其中nn为两位数字,K表示停止服务,S表示启动服务。
新一些的Linux系统会使用systemd
来选择运行级别,支持更灵活强大的服务配置。systemd使用target的概念来管理要运行的服务集合。
7个运行级别分别为:
运行级别 |
说明 |
对应systemd的target |
0 |
关机 |
poweroff.target |
1 |
单用户模式,通常用于系统修复。 |
rescue.target |
2 |
不完全的命令行模式,不含NFS服务。 |
multi-user.target |
3 |
完全的命令行模式,即标准的字符界面。 |
|
4 |
系统保留。 |
|
5 |
图形模式。 |
graphical.target |
6 |
重新启动。 |
reboot.target |
可以通过runlevel
命令来查看当前系统的运行级别。
root@localhost:~$ runlevel
N 5
其中第一个输出表示进入这个级别前,上一个级别是什么;第二个输出表示当前的运行级别。这里第一个输出是N, 即None;第二个输出是5,,说明是开机直接进入运行级别5的。
第六步:运行级别程序(Runlevel programs)
init进程确定了运行级别后,就开始执行运行级别下的所有程序。
- 执行rc.sysinit脚本。
- 启动内核模块。
- 执行
/etc/rc.d/rc${RUNLEVEL}
下的所有脚本。 - 执行
/etc/rc.d/rc.local
脚本。
不同的Linux发行版的具体配置会有不同。systemd会将init的运行级别服务映射为不同的target(见上表)。
在运行级别启动login服务后,就可以使用有效的用户名密码登录系统了。
参考
https://www.freecodecamp.org/news/the-linux-booting-process-6-steps-described-in-detail/