Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

8.2 启动与引导过程

我们每天开机的时候,计算机从按下电源键到进入操作系统桌面,中间经历了复杂的引导过程。理解系统的启动流程,有助于我们排查系统启动故障,理解操作系统的加载和初始化过程。

系统启动的完整流程

现代计算机从加电到操作系统启动完成,大致分为以下几个阶段:

加电 → BIOS/UEFI初始化 → POST自检 → 选择启动设备 → 加载引导加载程序 → 加载内核 → 内核初始化 → 启动用户空间服务 → 登录界面

下面我们详细讲解每个阶段。

阶段1:BIOS/UEFI初始化

按下电源键后,计算机首先会运行主板上固化的固件程序:BIOS或者UEFI。

BIOS(Basic Input/Output System,基本输入输出系统)

BIOS是传统的固件接口,已经有几十年的历史:

  • 存储在主板的ROM芯片中,计算机加电后首先运行
  • 负责最基础的硬件初始化和自检
  • 功能比较简单,使用16位模式,最大支持2.2TB的硬盘,MBR分区
  • 现在新的主板已经逐渐淘汰BIOS,改用UEFI

UEFI(Unified Extensible Firmware Interface,统一可扩展固件接口)

UEFI是BIOS的替代者,是现代计算机的标准固件:

  • 支持32位和64位模式,功能强大
  • 支持最大9.4ZB的硬盘,GPT分区
  • 图形界面,支持鼠标操作
  • 支持安全启动(Secure Boot),防止恶意软件篡改引导过程
  • 启动速度更快
  • 兼容BIOS启动模式

POST上电自检(Power-On Self Test)

BIOS/UEFI运行后首先执行POST自检:

  • 检查CPU、内存、硬盘、显卡等硬件是否正常
  • 如果硬件有故障,主板会发出蜂鸣声报错,屏幕显示错误信息
  • 自检通过后,初始化基本的硬件驱动(显卡、硬盘、键盘等)

选择启动设备

自检完成后,BIOS/UEFI会根据用户设置的启动顺序(U盘优先、硬盘优先、光驱优先等),尝试从对应的启动设备启动。

  • 每个启动设备的第一个扇区(512字节)是引导扇区,如果最后两个字节是0x55AA,说明这个设备是可引导的
  • BIOS/UEFI会把引导扇区的内容加载到内存,然后跳转到这个位置执行,把控制权交给引导加载程序

阶段2:引导加载程序(Boot Loader)

引导加载程序(Boot Loader)的作用是加载操作系统内核到内存,然后启动内核。

常见的引导加载程序

  1. GRUB(GRand Unified Bootloader):Linux系统最常用的引导加载程序,功能强大,支持多系统启动,可以引导Linux、Windows等系统
  2. Windows Boot Manager:Windows系统的引导加载程序
  3. systemd-boot:轻量级的Linux引导加载程序,用于systemd管理的系统
  4. UEFI Shell:UEFI自带的命令行Shell,可以手动执行引导命令

引导过程

以GRUB为例,引导加载程序的工作流程:

  1. 阶段1:BIOS/UEFI加载GRUB的第一阶段代码(存储在MBR的前446字节),功能很简单,加载第二阶段的代码
  2. 阶段1.5:加载文件系统驱动,这样就可以识别ext4等文件系统
  3. 阶段2:加载/boot分区下的GRUB配置文件,显示启动菜单,让用户选择要启动的系统或者内核版本
  4. 用户选择后,GRUB加载对应的内核文件和initramfs/initrd到内存
  5. 跳转到内核入口点,把控制权交给内核

MBR vs GPT分区表

硬盘的分区表有两种格式:MBR和GPT,和BIOS/UEFI对应。

MBR(Master Boot Record,主引导记录)

  • 传统的分区表格式,和BIOS配合使用
  • 存储在硬盘的第一个扇区(512字节),其中:
    • 前446字节:引导加载程序代码
    • 接下来64字节:分区表,最多只能记录4个主分区
    • 最后2字节:魔数0x55AA,表示是可引导设备
  • 最大支持2.2TB的硬盘,最多4个主分区(可以用扩展分区实现更多逻辑分区)
  • 现在已经逐渐被GPT取代

GPT(GUID Partition Table,全局唯一标识分区表)

  • 新一代的分区表格式,和UEFI配合使用
  • 最多支持128个分区,没有主分区扩展分区的概念
  • 最大支持9.4ZB的硬盘(1ZB=10亿TB)
  • 有冗余备份,分区表在硬盘头尾各存一份,损坏后可以恢复
  • 支持安全启动,更安全
  • 是现在新硬盘的标准分区格式

initramfs/initrd

initramfs(初始RAM文件系统)是一个微型的根文件系统,打包在镜像中,和内核一起加载到内存:

  • 包含了必要的驱动模块(硬盘驱动、文件系统驱动等)和工具
  • 内核启动时首先挂载initramfs作为临时根文件系统
  • 加载必要的驱动,然后挂载真实的根文件系统
  • 切换到真实的根文件系统,启动init进程
  • 作用:内核不需要包含所有硬件的驱动,减少内核体积,同时可以支持加载第三方驱动

阶段3:内核初始化

内核被加载到内存后,开始执行内核初始化:

  1. 内存初始化:检测系统内存大小,初始化内存管理模块
  2. 进程调度初始化:初始化调度器,创建0号 idle 进程和1号 init 进程
  3. 设备初始化:扫描所有硬件设备,加载对应的驱动程序
  4. 挂载根文件系统:根据引导参数指定的根分区,挂载真实的根文件系统
  5. 启动init进程:把控制权交给用户空间的1号init进程,内核态初始化完成,进入用户空间启动阶段

阶段4:用户空间初始化

内核启动完成后,启动用户空间的第一个进程(PID=1),负责启动所有用户空间的服务和程序。

init进程

init进程是用户空间的第一个进程,所有其他用户进程都是它的子进程:

  • 传统SysV init:旧的init系统,串行启动服务,速度慢
  • systemd:现在主流Linux发行版的init系统,并行启动服务,速度快,功能强大
  • launchd:macOS的init系统

以systemd为例,用户空间启动流程:

  1. systemd作为1号进程启动,读取配置文件
  2. 按照依赖关系并行启动系统服务:日志服务、网络服务、文件系统挂载、数据库、Web服务等
  3. 启动图形界面或者登录服务,显示登录界面
  4. 用户登录后启动桌面环境或者Shell,系统启动完成

不同操作系统的启动流程对比

Windows启动流程

  1. UEFI/BIOS初始化,POST自检
  2. 加载启动设备的EFI分区中的Windows Boot Manager
  3. Windows Boot Manager读取BCD(启动配置数据),加载Windows内核(ntoskrnl.exe)
  4. 内核初始化,加载驱动程序
  5. 启动smss.exe(会话管理器)、csrss.exe(客户端运行时子系统)、wininit.exe等系统进程
  6. 启动服务和登录界面,用户登录后启动explorer.exe资源管理器,进入桌面

macOS启动流程

  1. 按下电源键,运行BootROM,初始化硬件,POST自检
  2. 加载EFI引导程序,然后加载macOS内核
  3. 内核初始化,加载驱动,启动launchd进程(PID=1)
  4. launchd启动系统服务和代理程序
  5. 启动登录窗口,用户登录后加载桌面环境

启动常见问题排查

  1. 开机黑屏无反应:检查电源、硬件连接,POST自检失败,硬件故障
  2. 提示找不到启动设备:检查启动顺序设置,硬盘是否损坏,引导扇区是否损坏
  3. Grub Rescue模式:GRUB配置损坏,需要修复GRUB引导
  4. 内核panic:内核启动失败,可能是内核损坏、驱动不兼容、硬件故障
  5. 启动后卡住:查看系统日志,通常是某个服务启动失败,或者磁盘挂载错误

思考问题

  1. BIOS和UEFI有什么区别?UEFI相比BIOS有哪些优势?
  2. MBR和GPT分区表各有什么优缺点?为什么GPT逐渐取代了MBR?
  3. initramfs的作用是什么?如果没有initramfs会怎么样?
  4. 系统启动时如果显示“Operating System not found“,可能是什么原因?怎么排查?