UEFI可以理解为新一代的BIOS。
不同于传统BIOS开机启动先要进行硬件自检,若硬件异常会有蜂鸣报警;
UEFI直接初始化CPU和内存,硬件有问题会直接黑屏。
相比于传统的BIOS,UEFI开机启动速度更快,对新硬件的支持性更好。
计算机寻找被称为引导加载程序 的方式非常灵活,比如,
从硬盘中加载(一般使用GRUB2作为bootloader):
UEFI -> GPT硬盘分区 -> GRUB2
加载 /boot/efi/EFI/openEuler/grubaa64.efi ;x86_64的机器则是 grubx64.efi 文件
BIOS -> MBR硬盘分区 -> GRUB2
加载第一块硬盘第一个扇区中的 Stage 1 bootloader,然后再加载 Stage 2 bootloader
相关文件在该硬盘分区的 /boot/grub2 目录下。
或者通过网络下载(一般使用 PXE 或者 iPXE 作为bootloader):
BIOS/UEFI -> PXE
bootloader 文件为"pxelinux.0"
BIOS/UEFI -> PXE -> iPXE 方式
计算机使用 BIOS 启动,iPXE的文件为"undionly.kpxe";使用UEFI启动,iPXE的文件为"ipxe.efi"
BIOS -> MBR硬盘分区 -> GRUB2 -> iPXE
使用 BIOS 启动,开机加载硬盘上的 GRUB2,从GRUB2 去加载 iPXE 的程序文件。
需要预先将ipxe的程序文件放到 /boot分区下,并增加到 grub.cfg 的启动项,并设置以 iPXE的启动项重新启动。
CPU架构会影响BootLoader的引导过程,我们以 AArch64 为例,过程如下:
refer to: https://www.kernel.org/doc/html/latest/arm64/booting.html
在常用的 gurb.cfg 中的配置中,使用 GRUB2 的命令,指定 kernel image 和 initial ramdisk 就可以引导内核,进而启动操作系统。
示例如下:
linux /vmlinuz-4.19.90-btrfs-arm64 root=/dev/mapper/openeuler-root ro rd.lvm.lv=openeuler/root rd.lvm.lv=openeuler/swap smmu.bypassdev=0x1000:0x17 smmu.bypassdev=0x1000:0x15 crashkernel=1024M,high initrd /initramfs.lkp-4.19.90-btrfs-arm64.img
refer to: http://www.jinbuguo.com/systemd/systemd-fstab-generator.html
在网络引导的方式选择中,一般使用iPXE,以支持更多样的场景。
比如,在ipxe官网,有如下简介:
在后面的介绍中,会具体介绍compass ci 使用 iPXE 从网络引导操作系统的过程。
BootLoader 在加载 kernel和可能的initramfs文件之后,调用kernel。
内核将initramfs(初始RAM文件系统)归档文件解压到(当前为空的)rootfs(一个ramfs或者tmpfs类型的初始根文件系统)。
这是计算机启动过程中可以访问的第一个根文件系统,它的作用是挂载真正的操作系统。
在某些场景下,initramfs 也可以作为最终的根文件系统。
内核执行 initramfs 中的1号进程,现在一般是systemd。
Initramfs 是初始内存文件系统,它通常和 kernel 一起存放在/boot分区中,每次安装新内核时都会生成一个新的 initramfs。
默认情况下,initramfs归档文件只包含特定计算机需要的驱动程序。这使得存档更小,并减少了计算机启动所需的时间。
Initramfs 使用 dracut 进行管理,在一个安装好的系统上使用 dracut
命令可以直接创建一个适配当前运行内核的 initramfs 文件。
命令语法:# dracut [--force] [/PATH/TO/new_image_name] [kernel version]
其中 --force,表示覆盖/boot 目录下同名的 initramfs 文件。
Initramfs,也就是 dracut 的目的是挂载真正的根文件系统。
refer to: https://www.man7.org/linux/man-pages/man7/dracut.bootup.7.html
上面 GRUB2 的配置文件中,"root=/dev/mapper/openeuler-root" 指定根文件系统设备。
在使用initrd的系统上,该参数由initrd解析。
查看 dracut支持的内核参数
可以支持的选项如下:
在真正的根文件系统挂载之后,systemd 要完成的事情如下:
使用systemd-analyze critical-chain | grep target
命令,得到如下:
multi-user.target @39.632s
└─network-online.target @14.727s
└─basic.target @6.623s
└─sockets.target @6.603s
└─sysinit.target @6.479s
└─local-fs.target @5.959s
└─local-fs-pre.target @4.197s
以 ".target" 为后缀的单元文件,封装了一个由 systemd 管理的启动目标单元,用于在启动过程中将一组单元汇聚到一个众所周知的同步点。
使用systemctl list-dependencies multi-user.target
命令,还可以看到更清晰的启动依赖及顺序关系。
启动过程是高度并行化的,因此特定目标单元到达的顺序不是确定的,但仍然遵循有限数量的顺序结构。
Systemd 日志查看:journalctl