从按下开机键起,操作系统启动过程
揭秘linux系统启动流程,面试官问起来再也不怕了-阿里云开发者社区
BIOS -> MBR -> Boot Loader (e.g. GRUB) -> kernel -> mount initramfs as / -> /init
/ \ / |
UEFI -> GPT ----+ +----> initramfs --+ |
(memory) V
1 load drivers
run /sbin/init <--- 2 mount root
3 switch root
- 运行 BIOS(现代系统是 UEFI)。
- 进行开机自检(POST,即 Power-On Self-Test)。
- 寻找启动设备,依次检查存储设备,如果前 512 字节最后两个字节是 0x55 和 0xaa,那么这个块就是 MBR(主引导记录,Master Boot Record),这个存储设备就含有操作系统。然后根据 MBR 的信息找到 Boot Loader 位置,将其加载并运行。如果是 UEFI,UEFI 固件会读取磁盘上的 GPT (GUID Partition Table)。GPT 中有一个特殊的 EFI 系统分区 (ESP, EFI System Partition),通常格式化为 FAT32。UEFI 固件会直接在该分区中查找并执行引导加载程序文件(通常是 .efi 文件,例如 \EFI\ubuntu\grubx64.efi 或 \EFI\BOOT\BOOTX64.EFI)。它不依赖 MBR 的 0x55AA 签名来启动。
- Linux 常见的 Boot Loader 是 GRUB。Boot Loader 能理解文件系统,能显示操作系统选择菜单和加载 Linux 内核。
- GRUB 加载 (load) 内核 (vmlinuz-…) 和 initrd/initramfs 文件 到内存。加载完成后,GRUB 将执行控制权转交给已加载到内存中的内核。然后,内核会找到内存中的 initrd/initramfs 镜像,并将其解压(如果是压缩格式,如 gzip, xz),然后将其挂载为一个 临时的根文件系统 (rootfs)。
- 内核执行位于 initramfs 根目录下的 /init 程序 (通常是一个脚本或小程序,如 dracut 或 mkinitcpio 生成的),这个程序会加载必要的驱动模块,找到真正的根设备(可能是 /dev/sda2,或者 /dev/nvme0n1p3 等),将真正的根设备挂到临时路径如 /sysroot 上,然后切换根目录并释放 initramfs 的内存。
- 现在根目录已经切换好了,运行 /sbin/init 成为系统的第一个进程。内核引导阶段结束,用户空间初始化开始。