Appearance
启动与引导
学习了计算机组成原理,我们大致了解了寄存器、运算器、内存这些部件是如何一起工作的;通过汇编语言,我们也清楚了 C 语言这样的高级语言,最终是如何变成一条条机器能够执行的指令的。
但我们可能还会有些疑问:
- 当我们双击一个程序图标时,我们写的 C 程序代码是如何在计算机里“跑”起来的?
- 程序需要读写文件、在屏幕上显示文字或者播放视频时,它又是如何使用操作系统提供的这些功能的?
这些问题的答案,都指向一个默默无闻但极其重要的“总管家”——操作系统(Operating System,简称 OS)。OS 负责调度各个程序,合理分配和管理计算机的各种资源,确保整个系统能够流畅、高效并且安全地运行。
启动
按下电源键后,计算机内部发生了什么?为了理解这个过程,我们先看看硬盘分区的基本情况。下面以一个典型的硬盘为例(在 Linux 系统中,可以用 sudo parted -l 命令查看):
bash
sudo parted -l对于现在的计算机,启动过程通常依赖 UEFI 固件和 GPT(GUID Partition Table)分区表。在硬盘分区信息中,我们会看到一个 ESP(EFI System Partition)分区。这个分区的文件系统格式通常是 FAT(比如 FAT32),里面存放着操作系统或者其他工具的引导加载程序(bootloader)。
UEFI 启动流程大致如下:
- CPU 加电后,开始执行 UEFI 固件中的指令。
- UEFI 固件会检查计算机的硬件(如内存、硬盘等)是否正常,并对它们进行初步的初始化。
- UEFI 根据预设的启动顺序,从选定的存储设备(通常是 ESP 分区)加载一个指定的 EFI 应用程序。
- 这个 EFI 应用程序(即引导加载程序)接下来会负责加载操作系统的内核。
UEFI 提供了一个功能丰富的预启动环境,比如它已经为后续程序准备好了 64 位运行模式、内存分布信息、文件系统驱动(用于读取 ESP 分区)、网络协议栈甚至时间服务等。这使得编写 EFI 程序相对方便,可以直接用 C 语言来写,只需要在编译时使用特定的参数,然后将编译好的 EFI 程序放到磁盘上的 ESP 分区里即可。
在 2010 年以前的电脑上,更常见的是使用 BIOS(Basic Input/Output System)固件和 MBR(Master Boot Record)分区表。如今这种方式已经不多见了,我们可能只会在微机课程上见到。MBR 启动过程相对简单直接,能让我们看到更多底层细节,因此一些操作系统科普书籍仍会用它来举例。
MBR 分区方式规定,硬盘的第一个扇区(通常是 512 字节)被称为主引导记录,包含了小段的引导代码和硬盘的分区表。具体的启动流程如下:
- CPU 加电,开始执行 BIOS 固件中的指令。此时 CPU 通常运行在 16 位实模式(Real Mode)下。
- BIOS 检查硬件,初始化基本的中断向量表,然后把硬盘第一个扇区(MBR)的内容加载到内存的 0x7c00 地址处。
- BIOS 跳转到 0x7c00 开始执行 MBR 中的代码。由于 MBR 空间非常小,它的主要任务通常是加载一个更大、功能更全的“第二阶段引导程序”(Stage 2 bootloader),然后把控制权交给它。
引导
无论是 UEFI 还是 BIOS,在固件完成其初步工作后,接力棒就交给了引导加载程序(Bootloader)。引导加载程序的核心任务是找到操作系统的内核,把它加载到内存中,并最终启动它。
在 UEFI 环境中,直接加载并运行的 EFI 应用程序本身就是引导加载程序。它会负责解析文件系统,读取操作系统的内核文件和其他必要的启动文件到内存,然后跳转到内核的入口点开始执行。
以现代的 Windows 启动过程为例:
- UEFI 加载 Windows Boot Manager(
\EFI\Microsoft\Boot\bootmgfw.efi)。 - 如果 BCD(Boot Configuration Data)配置了多系统,会展示操作系统选择菜单。选择了指定系统(或者只有一个),
bootmgfw.efi会加载winload.efi。 winload.efi加载内核ntoskrnl.exe。
Grub 和 Linux 的过程略有不同:
- UEFI 加载
/EFI/BOOT/bootx64.efi。 bootx64.efi读取grub.cfg配置文件,显示启动菜单。- 根据配置加载内核
vmlinuz和初始化文件系统initramfs.img。
在 BIOS/MBR 环境中,由于 MBR 的空间限制,引导过程往往是分阶段的。
下面以 《30 天自制操作系统》 为例,其采用软盘作为启动介质。
- CPU 通电,BIOS 加载 MBR 到 0x7c00 至内存。
- MBR 代码非常简短,从后面几个扇区加载更复杂的 Stage 2 引导。
- Stage 2 需要以下初始化:
- 设置 GDT(Global Descriptor Table),开启 32 位 Protected 模式。
- 读取内核到指定内存位置。
- 初始化页表,为开启分页机制做准备。
- 准备工作完成后,跳转到内核的入口地址,操作系统正式开始启动。
对于像 Windows 或 Linux 这样成熟的操作系统,在使用 MBR 引导时,其过程可能更为复杂,常常分为三级或更多级:
- MBR:只负责识别活动分区,并加载该分区的第一个扇区,即 VBR(Volume Boot Record,卷引导记录)。
- VBR:包含针对特定文件系统的代码,它的任务是找到并加载文件系统中的“第二阶段引导程序”或者一个“过渡阶段引导程序”(Stage 1.5)。
- Stage 1.5:具备读取特定文件系统(如 NTFS、EXT4)中文件的能力,找到 Stage 2 引导程序。
- Stage 2:正式的加载内核并初始化所需驱动。