linux根文件系统是如何加载的

发布时间:2026/7/27 8:58:24
linux根文件系统是如何加载的 问题内核在磁盘文件系统中要加载内核就必须先加载文件系统。但根文件系统又是被内核负责加载的它是内核的启动参数没有它内核是无法启动的。到底先有鸡还是先有蛋机器是如何加载文件系统中的内核的1、在PC机中一般流程应该是bios先加载0扇区中的grub的第一段代码即stage1。stage1 然后加载 1~63扇区中的grub的第二段代码即stage1.5。stage1.5中有文件系统的驱动程序stage1.5 从文件系统中读出 grub最后一段比如/boot/grub/grub.cfg即stage2stage2 再 读取并启动内核内核启动时用自己的驱动读取磁盘挂载根文件系统。2、嵌入式环境中一般流程应该是BootROM读取并加载flash中的ubootuboot读取硬盘或另外一个flash中的文件系统找到内核启动内核。内核启动时用自己的驱动读取磁盘挂载根文件系统。3、如果根文件系统比较特殊比如是lvm加密盘等则内核是无法读取这个文件系统的就需要initramfsBootloader → 内核 initramfs(cpio) → initramfs 里加载模块/做解密/LVM激活 → 挂载真正的磁盘根fs → switch_root → 正常运行再详细一些bootloader 先加载内核并创建initramfs文件系统再把initramfs这个压缩包解压到文件系统中。内核执行这个文件系统中的init程序这个init程序 探测设备加载驱动挂载真正的文件系统执行真正文件系统中的 init程序进而使用switch_root 切换真正的用户空间。4、多系统引导的原理双linux系统 grub的 stage1 和 stage1.5 是两个系统公用的。grub引导时先加载主linux的stage2读取grub.cfg文件让用户选择要启动哪个linux。 如果用户选择启动另外一个linux就会去读取另外一个linxu的grub.cfg文件然后引导启动。linuxwindows系统 grub的 stage1 和 stage1.5 还是在0~31扇区中的。grub引导时先加载linux的stage2读取grub.cfg文件让用户选择要启动inux还是windows。 如果用户选择启动windowsgrub就会把windows分区的第一个扇区VBR读入内存并把控制器交给VBR即进行链式启动。GPT分区模式下安装系统时可以安装成bios和efi 兼容模式比如 $ sudo fdisk -l /dev/sdaDisk /dev/sda: 3.5 TiB, 3840653221888 bytes, 7501275824 sectors Units: sectors of 1 * 512 512 bytes Sector size (logical/physical): 512 bytes / 4096 bytes I/O size (minimum/optimal): 262144 bytes / 1048576 bytes Disklabel type: gpt Disk identifier: 99E1C9F8-D740-451A-81E2-B0BBF116031F Device Start End Sectors Size Type /dev/sda1 2048 22527 20480 10M BIOS boot /dev/sda2 22528 227327 204800 100M EFI System为啥要专门分一个bios 和 efi分区呢你看到的fdisk -l输出中/dev/sda使用的是GPT 分区表Disklabel type: gpt。在 GPT 格式下BIOS boot和EFI System分区是系统能够正常启动的“绝对前提”。简单来说它们的存在是为了解决主板固件Firmware与操作系统引导程序Bootloader如 GRUB之间的沟通问题。下面为你通俗地解释它们各自的职责1./dev/sda1(10M, BIOS boot)它是给谁用的专为传统 BIOSLegacy BIOS启动模式准备的。为什么需要它在老式的 MBR 分区表中引导程序GRUB的前半部分可以藏在硬盘最前面的 512 字节MBR和分区之间的空隙里。但 GPT 分区表没有这种空隙。为了让传统 BIOS 也能在 GPT 硬盘上启动GRUB 需要一块独立的“地盘”来存放它的stage1.5core.img。这个 10M 的 BIOS boot 分区就是专门用来装这段引导代码的。总结如果你用传统 BIOS 模式启动 GPT 硬盘这个分区必不可少。2./dev/sda2(100M, EFI System)它是给谁用的专为现代 UEFI 启动模式准备的。为什么需要它现代主板UEFI不再读取传统的 MBR 引导代码而是直接读取 FAT32 格式的分区里的.efi可执行文件。这个 EFI 分区通常格式化为 FAT32里面存放了操作系统的引导文件比如grubx64.efi以及主板自身的固件更新文件。主板开机时会直接去这个分区里找对应的引导程序来加载操作系统。总结如果你用现代 UEFI 模式启动这个分区是必须的。 为什么你的系统里这两个分区同时存在这通常是因为系统在安装时采用了“双模兼容”策略。安装程序同时创建了这两个分区这意味着无论你的主板设置成传统的 Legacy BIOS 启动还是现代的 UEFI 启动这块硬盘都能顺利引导系统。这提供了极大的灵活性特别是在需要更换主板或排查启动故障时。一、为什么 MBR 磁盘开头会有 1~63 扇区的空隙1.1 历史原因CHS 寻址与柱面对齐在古老的 CHS柱面/磁头/扇区时代磁盘的几何结构是每个磁道Track有 63 个扇区分区最好从一个柱面的起始即某个磁头的第 1 扇区开始以避免跨柱面带来的性能损失MBR 占据第一个柱面、第一个磁头、第一个扇区CHS0,0,1因此第一个分区从柱面 0、磁头 1、扇区 1 开始 → 相对 MBR 的偏移 63 个扇区MBR1 个扇区 保留的 62 个扇区第 2~63 扇区 共 63 个扇区被跳过这就是“第1~63扇区空隙”的历史来源。第一个分区是从64号扇区开始的。1.2 现代磁盘还保留吗是的兼容性考虑大部分分区工具如fdisk仍然默认按 1MiB 对齐2048 扇区空隙更大text旧式 CHS 对齐 空隙 63 扇区31.5KB 现代 1MiB 对齐 空隙 2048 扇区1MB实际上你执行fdisk -l /dev/sda时第一个分区的 Start 字段如果是2048就意味着 MBR 后面有 2047 个扇区未被第一个分区使用。什么时候用u-boot什么时候用biosbios也要自己下载编译吗 在 QEMU 中选择使用 U-Boot 还是 BIOS通常指 UEFI 固件以及是否需要自己编译主要取决于你的**开发目标**和**应用场景**。以下是详细的解答 ### 一、 什么时候用 U-Boot什么时候用 BIOS (UEFI) 这两者代表了不同的系统启动流程和硬件生态 **1. 什么时候使用 U-Boot** * **适用场景**主要用于**嵌入式 Linux 开发**、裸机开发或底层系统调试。 * **核心作用**在真实的嵌入式硬件上U-Boot 负责最底层的硬件初始化如设置 CPU 时钟、配置 DDR 内存控制器等然后才加载内核。在 QEMU 中使用 U-Boot可以让你深入学习和调试系统启动的每一个环节如手动加载内核、配置启动参数等非常贴近真实的嵌入式开发流程。 **2. 什么时候使用 BIOS (UEFI)** * **适用场景**主要用于运行**现代通用操作系统**如 Ubuntu、Debian、Windows 11 等或模拟服务器/云环境。 * **核心作用**现代操作系统通常要求运行在 UEFI 启动模式下。在 QEMU 中UEFI 固件如 QEMU_EFI.fd模拟了物理硬件上的 UEFI 芯片负责初始化虚拟硬件并在虚拟磁盘上寻找 EFI 系统分区ESP加载引导程序如 GRUB来启动系统。 --- ### 二、 BIOS (UEFI) 也要自己下载编译吗 **不需要。** 与 U-Boot 通常需要针对特定硬件或板卡自行编译不同UEFI 固件如 QEMU_EFI.fd通常有现成的预编译版本可以直接使用 **1. 随 QEMU 软件包自动安装推荐** 在大多数 Linux 发行版中当你安装 QEMU 及其 EFI 支持包时固件文件会自动放置在系统目录中。 * **Debian/Ubuntu**安装 qemu-efi-aarch64 包后文件通常位于 /usr/share/qemu-efi-aarch64/QEMU_EFI.fd 或 /usr/share/AAVMF/。 * **CentOS/RHEL**安装 edk2-aarch64 包后文件通常位于 /usr/share/edk2/aarch64/QEMU_EFI.fd。 我的环境中qenu是自己编译的会自动编译好bios 在 ~/code/gitlab/qemu/build 目录下已经编译好了 BIOS 固件 BIOS/UEFI 固件位置 路径: build/pc-bios/ 已编译的 BIOS/UEFI 固件文件包括 | 包括 - x86_64: - edk2-x86_2-x86_64-code.fd (3.5MB) - edk2-x86_64-secure-code.fd (安全启动版本) - i386: - edk2-i386-code.fd - edk2-i386-secure-code.fd - ARM/AARCH64: - edk2-aarch64-code.fd (64MB) - edk2-arm-code.fd (64MB) - RISC-V: - edk2-riscv-code.fd (32MB) - LoongArch: - edk2-loongarch64-code.fd (16MB) 这些 .fd 文件是 UEFI/BIOS 固件镜像可用于 QEMU 虚拟机启动。 **2. 直接下载预编译版本** 如果你使用的是 Windows 环境或者不想通过包管理器安装可以直接从开源社区下载预编译好的 QEMU_EFI.fd 文件。例如可以从 Linaro 的官方快照仓库或 EDK2 项目的发布页面直接获取。 **总结建议** * 如果你只是想**跑一个完整的 ARM Linux 系统**如 Ubuntu Server直接去系统目录找 QEMU_EFI.fd 并在 QEMU 启动命令中使用 -bios QEMU_EFI.fd 即可无需自己编译。 * 如果你是为了**学习嵌入式启动流程或做底层驱动开发**才需要去克隆 U-Boot 源码并使用交叉编译工具链自己编译 u-boot.bin。