使用带有文件的 U 盘选择 GRUB 2 条目

使用带有文件的 U 盘选择 GRUB 2 条目

我有一台装有 Windows 和 Ubuntu 20.04 的机器。活动分区(BIOS 中的第一个启动项)是安装 Ubuntu 的分区,我已手动在 GRUB 中输入条目以将 Windows 作为启动选项,这被设置为默认值。

我希望能够使用 USB 记忆棒(或者更好的是 SD 卡)来更改默认选择。如果已插入,则应启动至 Ubuntu(第一个条目),如果未插入,则应使用默认选择(第三个条目,Windows)。

我是否需要(不知何故,我不知道如何)将 GRUB 安装/复制/dd 到 USB 棒/SD 卡上,并将其选择为 BIOS 引导顺序中的第一项,并回退到 Ubuntu 分区,目前哪个是启动顺序中的第一个?

或者是否有(希望)有一个工具可以让我将文件放在棒/卡上,然后由 GRUB 读取?


更新:我一直在检查 GRUB 配置文件,并注意到有一个名为 的文件,/boot/grub/grubenv其中有一个名为next_entry=.这条线存在是因为我有时sudo grub-reboot 0使用重启进入Ubuntu。如果我执行,sudo grub-reboot 0那么该行将更改为next_entry=0.

我现在正在考虑修改/etc/default/grub/00_header以检查某个 USB 设备是否已连接,如果是,则它要么写入next_entry=0文件grubenv,要么添加一些代码,这些代码仅设置必要的变量,类似于如何next_entry=0执行此操作。

所以现在我的问题是,我不知道可以在 中执行哪些操作00_header,最终使用curl来获取变量将是完美的,但我想此时不存在网络并且curl 不是可识别的命令。

我如何调试/学习 GRUB 以了解此文件中的功能,而不会有损坏系统的风险?

我目前正在考虑使用带有快照的干净虚拟机,如果出现问题我可以恢复到该虚拟机,以便获得一些见解。但也许这里专家的一两个提示对我来说很有价值。

答案1

曾经有一个软件叫Multisystem。我看到它仍然存在。它通常是一个可以让您将多个发行版安装到 USB 记忆棒上的软件。你可以使用它的方式(我已经使用过它)是使用它来启动 grub(USB 闪存驱动器的 grub)。我看到一个较新的工具叫做 Ventoy,但我没有使用过它。看起来它有相同的方法。基本上,我的口袋里有 GRUB。否则我习惯启动进入Windows。我没有安装 grub(故意的),而且我也是双重启动的,使用 USB 记忆棒启动到 Debian。有更干净的方法可以做到这一点,但我认为这些会更容易。

答案2

如果您在 GRUB 2 选择菜单中中止引导过程并进入 shell,您将能够通过执行命令列出已连接的设备ls

就我而言,USB 记忆棒是(hd0,msdos1)

首先,我修改了该/boot/grub/grub.cfg文件,使其包含以下内容:

### BEGIN /etc/grub.d/00_header ###
if [ -s $prefix/grubenv ]; then
  set have_grubenv=true
  load_env
fi
# =================== BEGIN MODIFICATION ===================
if [ -s (hd0,msdos1)/grub_boot_config ]; then
  set next_entry=0;
fi
# =================== END MODIFICATION ===================
if [ "${initrdfail}" = 2 ]; then
   set initrdfail=
elif [ "${initrdfail}" = 1 ]; then
   ...

如果我跑了,会next_entry=0在哪里设置。$prefix/grubenvsudo grub-reboot 0

这可行,但它无法在内核升级后继续存在,因为它会重建/boot/grub/grub.cfg

然后我修改了/etc/grub.d/00_header添加以下内容:

cat << EOF
if [ -s \$prefix/grubenv ]; then
  set have_grubenv=true
  load_env
fi
EOF
# =================== BEGIN MODIFICATION ===================
cat << EOF
# =================== BEGIN MODIFICATION ===================
if [ -s (hd0,msdos1)/grub_boot_config ]; then
  set next_entry=0;
fi
# =================== END MODIFICATION ===================
EOF
# =================== END MODIFICATION ===================
cat <<EOF
if [ "\${initrdfail}" = 2 ]; then
   set initrdfail=
elif [ "\${initrdfail}" = 1 ]; then
   ...

并发出sudo update-grub,然后生成/boot/grub/grub.cfg

结果是,如果插入 USB 记忆棒并且它grub_boot_config在根目录中包含该文件(可以为空),则将(hd0,msdos1)/grub_boot_config成功并设置next_entry=0.

下一步的改进是0在文件中包含(或应启动的任何菜单项),并让脚本读取它并设置next_entry它,并使其在每个驱动器上搜索该文件,而不仅仅是(hd0,msdos1).

无论如何,事实证明它对/boot/grub/grub.cfg拼写错误的恢复能力非常强,因此您不太可能通过进行这些修改来破坏系统(我使用干净的虚拟机进行了测试)。

相关内容