计算机启动流程#
ROM -> LOADER -> RUNTIME -> OS LOADER -> OS
- Loader:常见的包括 BIOS 和 UEFI(后者是前者的继任者),一般就是内存初始化,以及加载 Runtime 和 OS Loader 程序。
- Runtime:固件程序是为了提供运行时服务,它是对硬件最基础的抽象(给 OS 提供一系列抽象)。
- OS Loader:或者也也有很多人称作
BootLoader
。它需要做:文件系统引导、网卡引导、操作系统启动配置项设置、操作系统加载等等。常见的 OS Loader 包括 GRUB、U-Boot、LinuxBoot 等。
UEFI 如何寻找 Loader 并启动#
现在用的更多的是 UEFI 来做 Loader,而非 BIOS,保留 BIOS 名称只是口头的习惯。主板的 UEFI 固件只认识 efi
格式的文件,所以不能加载 elf
格式的内核。这时候就需要 OS Loader,它是一个承上启下的角色,在 UEFI 方,会将自己包装为 efi
格式,并保存在硬盘特定位置;如果面对 kernel
,则会解析 elf
格式并加载。
这样计算机在启动阶段才能顺利找到 Loader,并进一步加载运行 OS。Loader 实际上就是是程序的格式。Loader 所处的特定位置,要求位于启动设备的 FAT32
格式分区,然后在这个根目录下新建 efi
目录,并在 efi
目录下新建 boot
目录,计算机固件就会按照这个固定路径寻找 Loader,里面放着 Bootx64.efi
必须遵守的规范(如果是 32 位系统,则不能带 64)。
这个 FAT32
分区一般位于整个磁盘的最开始位置,大小大约 100M 左右(也可以是 GB,甚至更多,比较灵活),UEFI 固件会把存在 FAT32
格式分区的磁盘都当作启动磁盘,并把这些发现的磁盘都添加到开机菜单里,至于能不能启动,先不管,当选择一个具体的目标,如果是带 UEFI 前缀的就去搜索固定路径(/efi/boot
找 loader
)
同样,Loader 查找 kernel
文件也是如此,也将 kernel
文件放在同一目录。当 Loader 找到 kernel
文件,就按照 elf
文件格式进行解析,如果是可以运行的 elf
文件,就读取到内存并跳转运行。
那 kernel 在 FAT32 分区如何读区?#
这就是 UEFI 存在的目的,不必去考虑要加载到哪块内存,段式还是分页。它会在启动阶段和运行阶段提供非常丰富的服务供开发者调用。启动阶段的服务称为启动时服务,顾名思义,这些服务只在启动时可用;而运行时服务就是在计算机结束启动进入正常运行后也是可以使用的。这些都在 UEFI 的接口提供。