创建一个自动检测EFI系统的grub脚本,并启动第一个系统



我正在开发一个开源项目bluebanquise,该项目旨在部署裸机基础设施,现在我们支持RHEL/CNTOS8发行版,我希望添加其他RHEL衍生发行版(Rocky Linux、Oracle Linux、Cloud Linux等(,但也希望在未来添加其他非RHEL发行版(Ubuntu、OpenSuse等(。

默认情况下,在我们的基础设施上,所有服务器默认通过PXE启动。DHCP提供了一个iPXE rom,它链接到其他iPXE文件等。在这个链的某个时刻,如果服务器必须在磁盘上启动(因此不在无盘中部署或启动(,并且如果服务器在EFI中,iPXE链接到一个grub2映像,该映像带有一个嵌入脚本,试图检测已经安装的操作系统并启动找到的第一个操作系统。

注意:也许这不是在EFI中从iPXE引导到磁盘的最佳解决方案。但我什么也没发现。

脚本如下:grub2-efi-autofind.cfg

基本上,它搜索适用于RedHat或CentOS Linux的grub.cfg文件,如果找到,则使用它们进行引导。但现在,我想把这个剧本做得更加"通用";,因此,它可以绕过分发名称的需要,只查找任何/efi/*/grub.cfg文件。

然而,我无法创建一个能够做到这一点的脚本:-(

我在这个页面上找到了一个有趣的脚本,但我没能根据需要调整for循环。我试着单独使用它:

for efi in (*,gpt*)/efi/*/grub.cfg ; do
regexp --set=1:efi_device '^((.*))/' "${efi}"
echo found efi
echo "${efi}"
echo "${efi_device}"
echo "${2}"
echo "${1}"
sleep --interruptible --verbose 10
done

但这不输出任何东西;(,gpt(/efi/*/grub.cfg";

我尝试使用这个页面的纯代码,它确实检测到了文件,但在自动菜单中进行了几次迭代后(我需要在detect EFI bootloaders上按两次才能获得正确的路径(。这不是自动的。

GRUB2文档中没有太多与此相关的示例,我也没有在网络上找到很多关于这一问题的交流。

如果你们中的一个人知道从iPXE rom在磁盘上启动EFI系统的更好方法,或者如果你知道如何用静态路径替换search.file,从而通用地检测EFI分区中的任何grub.cfg,我会很高兴阅读它!:-(

非常感谢你读到这篇文章,即使你没有答案。

向致以最良好的问候

Ox

这里有一个简单的GRUB脚本,用于搜索第一个"磁盘";在/EFI/BOOT/BOOTX64.EFI包含一个文件,然后有条件地显示要从中启动的菜单项:

search --no-floppy --file --set=bootable_efi /EFI/BOOT/BOOTX64.EFI
if [ -n "${bootable_efi}" ]; then
menuentry "EFI Bootable USB" --class unknown {
set root="${bootable_efi}"
chainloader /EFI/BOOT/BOOTX64.EFI
boot
}
fi

我终于找到了一种方法,添加了大量的回声和睡眠,我能够找到一种有效的模式:

echo " Loading modules..."
insmod part_gpt
insmod fat
insmod chain
insmod part_msdos
insmod ext2
echo
echo "Scanning, first pass..."
for efi in (*,gpt*)/efi/*/grub.cfg (*,gpt*)/efi/*/*/grub.cfg (*,gpt*)/grub.cfg (*,gpt*)/*/grub.cfg ; do
regexp --set=1:efi_device '^((.*))/' "${efi}"
done
echo "Scanning, second pass..."
for efi in (*,gpt*)/efi/*/grub.cfg (*,gpt*)/efi/*/*/grub.cfg (*,gpt*)/grub.cfg (*,gpt*)/*/grub.cfg ; do
regexp --set=1:efi_device '^((.*))/' "${efi}"
if [ -e "${efi}" ]; then
efi_found=true
echo " >> Found operating system! <<"
echo " Path: ${efi}"
echo " Booting in 5s..."
sleep --interruptible --verbose 5
configfile "${efi}"
boot
fi
done

然而,尽管它有效,我不明白为什么。。。基本上,第一次执行for循环时,grub什么也找不到。第二次执行循环时,会找到文件。所以这里的解决方法是第一次循环,什么都不做,然后用条件和引导再次重做。

如果有一天有人了解这里发生了什么,我很感兴趣:-(就目前而言,它就像一种魅力。

相关内容

  • 没有找到相关文章