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

问题描述

我正在开发一个开源项目 bluebanquise,旨在部署裸机基础架构,现在我们支持 RHEL/CentOS 8 发行版,我希望添加其他 RHEL 衍生发行版(Rocky Linux、Oracle Linux、 Cloud Linux 等),但将来还会有其他非 RHEL 发行版(Ubuntu、OpenSuse 等)。

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

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

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

基本上,它会为 RedHat 或 CentOS Linux 搜索 grub.cfg 文件,如果找到则使用它们进行引导。 但是现在,我想让这个脚本更“通用”,这样它就可以绕过发行版名称的需要,只查找任何 /efi/*/grub.cfg 文件。

但是,我无法创建能够做到这一点的脚本:-(

我在 this page 上发现了一个有趣的脚本,但我未能根据我的需要调整 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 系统的更好方法,或者如果您知道如何通过一般检测 efi 中的任何 grub.cfg 的方式用静态路径替换 search.file分区,我会很高兴阅读它! :-)

非常感谢您阅读本文,即使您没有答案。

致以最诚挚的问候

解决方法

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

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*)/*/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 什么也没找到。 第二次执行循环时,找到了文件。所以这里的解决方法是第一次循环,什么都不做,然后用条件和引导再做一次。

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

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...