操作系统的启动
在进行开发和实验之前,我们有必要讲一下操作系统的启动过程。操作系统(OS)的启动过程因设备类型不同(通用计算机与嵌入式设备)而略有差异。但总体上可以归纳为三阶段:
- 第一步 板载固件:上电后,首先执行的程序便是板载固件,它可能提供了一些固件检测、配置设备的功能,但它主要还是用于加载第二步的引导程序
- 第二步 引导阶段:引导程序(Bootloader)的主要功能是引导操作系统内核,使其能够正常运行。它还可能为内核提供启动所需的参数
- 第三步 操作系统内核:操作系统内核被加载到内存,开始执行
固件
BIOS的概念由Gary Kildall在开发CP/M操作系统时首次提出,它的作用是为操作系统提供硬件抽象层,以便在不同硬件平台上运行,后来随着计算机软硬件技术的发展,BIOS逐渐被UEFI取代。
如今,许多通用计算机设备都自带UEFI固件,计算机上电后,首先执行UEFI固件:
- 初始化硬件设备,例如CPU、内存、键盘、显示器等
- 执行电源自检(POST, Power-On Self-Test),检查硬件状态是否正常
- 查找启动设备(如硬盘、U盘、网络)并加载引导程序(Bootloader)
- UEFI还支持图形界面、网络引导以及更大的分区表(GPT)
引导程序
在我们的常见的个人计算机中,操作系统内核通常位于磁盘的某个分区中,磁盘使用GPT、MBR分区格式。现代操作系统会使用特定的引导程序加载内核,常见的引导程序有:用于Linux内核的引导程序GRUB、嵌入式引导程序Uboot、Windows Boot Manager。
以从磁盘启动,GRUB引导为例,UEFI程序首先寻找可启动的设备,从磁盘的EFI系统分区加载引导程序,引导程序可能会提供以下的功能:
-
硬件初始化
-
配置必要的硬件设备,例如CPU、内存控制器、中断控制器等
-
为后续的系统启动做好准备,包括设置时钟频率、初始化缓存(Cache)和内存管理单元
-
-
加载操作系统内核
- 从指定的存储设备(如硬盘、SD卡、网络或其他非易失性存储器)加载内核映像到内存中
- 解析和加载其他必要的启动文件,例如设备树(Device Tree)、初始RAM盘(initramfs)或驱动程序
-
内核启动前的配置
- 提供内核启动所需的参数,例如启动命令行参数
- 设置内存映射或其他资源分配,确保内核在加载后能正确使用系统资源
- 如果使用多核处理器,可能需要进行初步的多核配置
-
引导流程管理
- 支持多种引导模式,例如单用户模式、调试模式、恢复模式
- 实现引导菜单,供用户选择不同的内核或操作系统版本
-
错误处理
- 在加载内核或初始化硬件过程中发生错误时,提供诊断信息或提示用户采取措施
- 记录错误日志,便于调试和排查问题
-
用户交互
- 提供用户接口,用于选择引导选项或修改引导配置
- 一些高级引导程序还支持脚本化引导流程
操作系统内核
最后,引导程序将操作系统内核加载到内存中,并将CPU控制权交给操作系统内核,系统内核会:
- 初始化硬件和驱动程序
- 建立虚拟内存管理
- 创建系统进程
- 挂载根文件系统,启动用户空间服务,完成系统启动