Linux-按下开机键后,究竟发生了什么

“你来说说linux系统的启动过程是什么样的?” ,这个问题相信大家经常听到,只要是linux系统知识相关的面试,很大概率面试官都会问到这个问题。那今天就来说明一下,对于linux系统来说,按下服务器开机键后,究竟发生了什么。以centos7为例,先通过一个图来看下从服务器开机到系统启动的过程

 

 

 

 

下面我们来一步步拆解,对于linux系统来说,从按下服务器电源键到系统完全启动究竟是怎样一个过程。

 

BIOS

bios为基本输入输出系统,主要负责两部分POST自检和加载MBR

  • POST自检:读取CMOS RAM中的信息来识别硬件配置并对硬件进行自检测试和初始化操作。
  • 加载MBR:读取启动设备列表,从第一个可启动设备加载引导加载程序(如硬盘、光驱、USB设备等)

 

MBR

MBR即主引导记录,位于可启动设备(如磁盘)的第一个扇区,大小为512字节,最后两个字节以55AA结束。

 

 

当POST自检结束后,BIOS会将可启动设备的第一个扇区(MBR扇区)读入内存地址0000:7c00H处。接着会检查0000:01FEH到0000:01FFH这段地址的值是否为55AAH,如果不等于,则尝试其他启动设备。如果等于,BIOS将控制权交给相应的启动设备。MBR会将自身复制到内存0000:0600H处,然后根据MRB中的引导代码启动引导程序(即grub

我们可以通过以下方式查看启动设备中的mbr信息

dd if=/dev/vda bs=512 count=1 | hexdump -C

 

 

通常来说,BIOS除了检查MBR的结束标志位是否等于55AAH外,还会检查磁盘是否有写保护、主引导扇区中是否存在活动分区等。

 

GRUB

grub是一个用于加载和管理系统启动的完整程序。最主要作用都是将内核加载到内存并运行。目前的linux发行版大都使用grub2取代了较旧的 grub引导加载程序。

grub由几个映像文件组成,引导镜像boot.img、内核映像kernel.img、核心镜像core.img。核心镜像由一组模块和kernel.img组成。我们在/boot/grub2/i386-pc/或/usr/lib/grub/i386-pc/目录下能看到相应的镜像和模块文件。

 

 

从leagcy模式下启动内核,bootloader至少包含两块二进制的程序代码,分别是boot.img与core.img。boot.img是grub启动的第一个程序,位于mgr的前446字节bootloader中。这块空间的大小使得boot.img程序能实现的功能有限,因此它无法理解文件系统,core.img的位置是硬编码在boot.img中的。boot.img中唯一做的事情就是读取core.img的第一个扇区,然后将控制权移交给core.img再由core.img来完成内核的加载操作。因为core.img的位置是硬编码在boot.img中的,所以如果移动了core.img在磁盘上的位置却没有重新生成boot.img的话,很可能会导致操作系统启动失败。

 

 

boot.img启动后会找到core.img扇区的地址,将它拷贝到0x8000处运行,同时通过biso中断读取到core.img里的kernel.img(前面提到过core.img由kernel.img和一些mod组成),然后将控制权交给kernel.img。

kernel.img会调用grub_load_modules()来加载各个mod模块,模块加载后就能识别文件系统了。接着kernel.img再调用grub_load_normal_mode()加载normal模块。normal模块会先读取并解析grub.cfg,接着再根据command.list定位并加载linux模块(/boot/grub2/i386-pc目录下)。下一步就是初始化屏幕显示、载入字体、展示grub菜单

 

 

grub2 配置文件位于 /boot/grub2/grub.cfg

 

 

 

kernel

grub会在 /boot 目录中搜索压缩的内核映像文件,通常称为 'vmlinuz'。这个文件包含内核的基本代码,是系统继续运行的前提。找到后,grub 将 vmlinuz 内核映像文件加载到内存中。随后,grub 解压 initramfs 映像文件的内容,建立一个基于内存的临时文件系统,称为 tmpfs。

 

 

initramfs是一个被压缩过的小型根目录,这个目录里包含了启动阶段中所必须的驱动模块、可执行文件以及启动脚本。当系统启动的时候,bootloader会把内核和initramfs⽂件读到内存中,然后把initramfs的起始地址告诉内核。

 

内核在运⾏过程中会解压initramfs,然后把initramfs挂载为根⽬录,然后执⾏根⽬录中的/initrc脚本,可以在这个脚本中运⾏initrd中的udevd,让它来⾃动加载设备驱动程序以及 在/dev⽬录下建⽴必要的设备节点。在udevd⾃动加载磁盘驱动程序之后,就可以mount真正的根⽬录,并切换到这个根⽬录中。接着系统的第一个进程systemd就启动了。

 

systemd

systemd 是所有进程的父进程。它负责将 Linux 主机带到一个用户可操作状态(可以执行功能任务)。Systemd 读取 /etc/systemd/system/default.target 链接的文件(例如 /usr/lib/systemd/system/multi-user.target)来确定默认系统目标(相当于运行级别)。同时systemd还会为系统做一些初始化工作

1. 设置主机名

2. 初始化网络

3. 根据配置初始化 seLinux

4. 打印欢迎横幅

5. 根据内核启动参数初始化系统硬件

6. 挂载文件系统,包括虚拟文件系统,如 /proc 文件系统

7. 清理 /var 中的目录

8. 启用swap

系统启动的第一个进程systemd

 

 

 

上面就是linux系统的整个启动流程,简单描述如下图

 

 

详细描述如下图

 

 

 

关注公众号 singless,获取更多有价值的文章

posted @ 2025-10-29 14:10  singless233  阅读(11)  评论(0)    收藏  举报