背景: 传统legacy启动的机器,能否适配uefi 启动模式,使能系统从uefi 启动。
UEFI 启动引导文件是安装在 EFI 分区(EFI system partition ESP )的,分区大小通常在 100 -500 M 左右,且 efi 分区只支持FAT 文件系统(FAT12 FAT16 FAT32)。
UEFI 启动下系统分区通常是GPT格式的,传统legacy 使用MBR格式分区,相比MBR,GPT格式可以支持更大(2T以上)的分区大小。
legacy 兼容适配uefi
第一步 创建EFI分区
对非系统盘的磁盘进行分区,创建EFI 分区。注意备份数据。建议给虚拟机挂载1G大小的空磁盘(vdb),避免影响系统/数据。
需要将磁盘格式化成fat 文件系统类型,及 gpt格式分区
mkfs.fat -F32 /dev/vdb parted -s /dev/vdb mklabel gptmkfs.fat 可以通过下载 dosfstools 来获取。
格式化磁盘后,使用gdisk 工具,给磁盘分区,创建EFI 分区 gdisk /dev/vdb, 分区大小 100-200M就可以了。
给创建的分区设置系统类型时,输入编号 EF00(小写ef00也可以)。就设置该分区是 EFI 分区了。
gdiks 分区时的系统类型对应的编号 详见下表
EFI 分区设置好后将根分区 挂载到 /data (需要先创建下) 下, EFI 分区就设置好了。
梳理整个EFI 分区的创建过程,可以看到与系统的启动模式无关,bios/uefi 系统都可以完成这个步骤。
第二步,在EFI 分区安装grub
安装grub 需要用到 gurb2-install
安装bios 的gurb 时, 使用的命令是 grub2-install target=i386-pc /dev/vda。 安装UEFI 的 grub 时,需要加上 --efi-directory 参数 指定EFI 分区的路径。为了方便调试,可以再后面加上 --debug 参数,查看详细过程。
grub2-install --target=x86_64-efi --efi-directory=/data --bootloader-id=centos--target 参数是指要安装grub的平台,在bios 中该处参数是 i386-pc,在UEFI中,是x86_64-efi。这里需要安装grub2-efi-x64-modules.noarch 这个包,提供该模块。
--bootloader-id 这个参数
命令后面没有跟EFI 分区的磁盘device(/dev/vdb) ,这块可以不用写,即使提供了 device 参数,grub2-install 也会忽略。
在bios 启动的系统上执行改步骤时,执行结果如下图
加上 --debug 上,查看如下
在执行 efibootmgr时报错,因为系统不是EFI启动的,没有相关变量。导致添加系统项失败。
关于efibootmgr,:是 UEFI 启动管理工具,在下图的文档中有说明,要成功执行efibootmgr 来添加启动项,需要使得 efibootmgr 能获取到EFI 变量,这就要求系统是从EFI 启动的,否则EFI 变量就无法获取。
安装grub, grub2-mkconfig -o /data/EFI/centos/grub.cfg
修改grub 中的filename 为 linuxefi
切换虚拟机的bios 参数,以UEFI 模式启动虚拟机,进入UEFI shell
在UEFI shell 中调试引导启动系统
执行 grubx64.efi 引导启动,该文件会读取grub.cfg 启动系统
此时,系统便以UEFI 模式启动系统了。 若在启动中因grub 参数问题导致启动失败,可在启动界面中出现版本信息时按 e 来修改grub 按ctrx + X 或者 F10 来启动系统。
结论:BIOS 启动系统,在创建EFI 分区,安装grub 引导文件后,切换uefi 启动,(目前调试结果是需要在UEFI shell中导引进入),可以进入系统。
下一步: 解决 efibootmgr 不能正常引导EFI 启动问题。
参考链接
https://wiki.archlinux.org/index.php/GRUB_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)#Chainload_%E4%B8%80%E4%B8%AA_Arch_Linux_.efi_%E6%96%87%E4%BB%B6
https://wiki.archlinux.org/index.php/EFI_system_partition#Mount_the_partition
https://en.wikipedia.org/wiki/Unified_Extensible_Firmware_Interface
https://wiki.archlinux.org/index.php/GPT_fdisk_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)
https://en.wikipedia.org/wiki/Unified_Extensible_Firmware_Interface