一般一个从硬盘启动的linux系统的启动顺序是:UEFI->GRUB->Linux。其中,我们一般称
UEFI是固件,GRUB是bootloader.
顾名思义,一般我们认为固件是固化在系统里的,启动会自动加载、执行的一段代码,这
里我们不关心固件的存储位置。一般,bootloader和linux kernel镜像都是放在磁盘上
(我们这里只看磁盘启动的情况,不关心网络启动,e.g. PXE)。
UEFI在加载bootloader(e.g. grub)的时候会从EFI system分区寻找grub程序(e.g. grub.efi).
这个程序是一个UEFI环境中的可执行程序。一般,UEFI里会在EFI system分区上的一组路径
上搜索grub.efi,这组路径是提前在UEFI静态配置好的。EFI system分区必须被格式化成
FAT文件系统,这样UEFI才可以读取其中的文件。grub.efi加载后,会找见它对应的配置
文件grub.cfg. 在grub.cfg中,我们可以配置grub到哪里去加载kernel镜像, 以及到哪里去
加载根文件系统. 一个grub.cfg的配置类似:
1 | # Sample GRUB configuration file |
其中上面的UUID是存放Image的分区的UUID, PARTUUID是存放根文件系统的分区的PARTUUID.
UUID, PARTUUID可以事先用blkid得到,比如:
1 | [root@localhost ~]# blkid |
按照上面的配置做的系统只是一个临时可用的系统,在系统启动之后,如果不加入其他的
操作,启动分区(上面存放Image, grub.efi, grub.cfg)是没有办法挂在到根文件系统上的。
这样,如果我们想把内核编译成一个RPM包,然后用rpm -i kernel-package安装到系统,
使得下次系统启动的时候可以用新安装的内核,这样是不可能的。
rpm -i kernel-package的时候会把相关的配置加载grub.cfg里。to do…
实际上一个标准的ISO安装是这样的, 安装过成应该会自动的分区和在启动分区里放置相应
的文件,并且更改/etc/fstab里的内容,实现开机自动挂在启动分区到/boot. to do…
一个例子:
- 磁盘分区: fdisk [4]
- 拷贝grub.efi, grub.cfg, kernel Image到对应的EFI system分区
- 更改grub.cfg里的参数, 主要是修改上面提到的UUID和PARTUUID
- 拷贝文件系统到PARTUUID对应的分区里
reference:
[1] http://www.rodsbooks.com/linux-uefi/
[2] https://en.wikipedia.org/wiki/EFI_system_partition (install bootloader)
[3] http://www.rodsbooks.com/efi-bootloaders/installation.html
[4] https://github.com/open-estuary/estuary/blob/master/doc/Deploy_Manual.4D05.md#3.3
[4] https://github.com/open-estuary/estuary/blob/master/doc/Deploy_Manual.4D05.md#3.3