我刚刚在一台运行 Windows 10 的 UEFI 笔记本电脑上安装了 Ubuntu 18.04 LTS,无论我怎么尝试,每次启动时都会出现类似 Grub bash 的命令行 ( grub>
)。运行后set
显示,每次启动时,root 和 prefix 都设置为 (hd0,gpt1) 和 (hd0,gpt1)/boot/grub,而它们都应该设置为 (hd0,gpt8)。因此,我将它们设置为正确的值,运行normal
,然后我进入 Grub 引导加载程序,从那里我可以启动到 Ubuntu 或 Windows - 一切正常。
但是到了 Ubuntu 之后,问题update-grub
并grub-install
没有彻底解决。下次重启时,根目录和前缀将恢复为 (hd0,gpt1)。到目前为止,我尝试过:
update-grub
,,grub-install
initramfs -v -u
- 运行启动修复(尝试清除、nodmraid)
- 在 USB 上运行 Super Grub2 Disk(查找 .cfg 文件)
- 重新安装 Ubuntu(两次)
bcdedit
通过将 .EFI 复制到启动分区并使用PowerShell更新 BCD 存储来运行 Super Grub2 Disk
有趣的是,当我尝试从 EFI 运行 Super Grub2 Disk 时,它遇到了同样的问题,并且只显示 Grub2 bash 命令行。我只想能够进入 grub 菜单,而不必每次都设置前缀和 root。如果能得到任何帮助,我将不胜感激,因为我已经为此苦恼了大约两天!
答案1
对于那些有类似问题的人,请指定您尝试引导的分区。该set
命令根据正在加载的分区输出前缀和根。就我而言,这是(hd0,gpt1)
在需要加载时(hd0,gpt3)
。因此,将第一个分区的引导优先级更改为第三个分区就解决了问题。
答案2
有可能是从/boot/efi/EFI/ubuntu/grub.cfg
这是一个文本文件,只有 root 权限才能访问。但是一旦进入,只需更改一些文本即可。
在我的 Kubuntu 22.04 系统上,该文件的内容如下:
search.fs_uuid 73ffa900-dca2-47f2-9e0b-f8c1942ef918 root hd0,gpt2
set prefix=($root)'/@/boot/grub' ## Change this line
configfile $prefix/grub.cfg
在某些发行版中,它可能被硬编码在 EFI 目录子目录中的二进制文件中;这将很难改变。
答案3
我找到了一个可以永久更改前缀的解决方案。但是,它有以下注意事项:我们必须直接在 grubx64.efi 二进制文件中更改它,并且必须保持文件的长度相同。您获得的空间大小可能取决于您的发行版。请继续阅读以了解更多说明。
免责声明
- 如果你想做到这一点,你必须关闭安全启动因为哈希值会发生变化,二进制文件会被拒绝。不确定是否可以通过安装自己的哈希值(搜索 MOK)来解决这个问题。
- 始终备份您正在更改的文件。如果您像我一样,您将能够使用可启动的 USB 棒撤消您的更改。如果您手头没有其他系统,请立即创建可启动的 USB 并测试您是否可以启动它。
首先是问题:
基本上,整个问题都是安全启动的限制。要使安全启动接受 grubx64.efi 文件,该文件必须由公认的机构签名。因此,此 grub 可执行文件已签名并预烘焙。设置此前缀的当前标准似乎是/EFI/$(lsb_release -i -s)
。这当然也意味着 - 无论您在创建新的启动选项时指定哪个加载程序路径(例如efibootmgr--loader \\EFI\\other\\SSHIMX64.efi
),它都不会对 grub 引导加载程序中的前缀变量产生任何影响。
解决方案:
假设我们的发行版是ubuntu
,并且我们想longubuntu
出于某种原因将其重命名为,我们可以按照以下步骤进行操作:
# List contents of EFI directory
find /boot/efi/EFI;
# Rename the directory
mv /boot/efi/EFI/ubuntu /boot/efi/EFI/longubuntu;
# List contents of EFI/longubuntu for easy access
find /boot/efi/EFI/longubuntu;
# Always make a copy of the original
cp /boot/efi/EFI/longubuntu/BOOTX64.CSV /boot/efi/EFI/longubuntu/BOOTX64.CSV.bak
# Inside the .csv-file change 'ubuntu' to 'longubuntu'
nano /boot/efi/EFI/longubuntu/BOOTX64.CSV
继续之前:
检查二进制文件中是否有足够的空字符。保持总长度相同很重要。如果不这样做,它会抛出错误 - 如果发生这种情况,请复制回原始 grubx64.efi 并重试。当使用 VS Code 检查我的 grubx64.efi-binary 时,我确实有足够的可用内容来将前缀更改为我想要的内容:
现在到了有趣且关键的部分:
正如我之前所说,我们需要确保二进制文件的长度相同。我们可以用空字符填充新前缀(\0
)或用空字符填充要替换的文本来实现这一点。
因此,如果您想指定更长的前缀(如我的情况),您可以这样做:
# Parameter -pi.bak will create a backup for you
perl -pi.perlbak -e 's/EFI\/ubuntu\0\0\0\0/EFI\/longubuntu/g' /boot/efi/EFI/longubuntu/grubx64.efi
如果您选择较短的前缀(例如bent
),则使用以下方式填充新值\0
:
# Parameter -pi.bak will create a backup for you
perl -pi.perlbak -e 's/EFI\/ubuntu/EFI\/bent\0\0/g' /boot/efi/EFI/longubuntu/grubx64.efi
您可以使用来检查操作结果,它将打印包含前缀的行。
$~: grep -a 'EFI\/longubuntu' /boot/efi/EFI/longubuntu/grubx64.efi
不要忘记添加新的启动选项!
我将使用efibootmgr
。efibootmgr
我们可以删除旧的启动选项并添加一个新的。
# Print current boot options
:~# efibootmgr -v
BootCurrent: 0000
Timeout: 1 seconds
BootOrder: 0000
Boot0000* ubuntu HD(1,GPT,28bd5547-5802-4f9c-97da-22ddd968dea6,0x800,0x100000)/File(\EFI\UBUNTU\SHIMX64.EFI)
# Delete current
:~# efibootmgr -b 0 -B
# List disks
:~# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
[...]
nvme0n1 259:0 0 238.5G 0 disk
├─nvme0n1p1 259:1 0 512M 0 part /boot/efi
└─nvme0n1p2 259:2 0 238G 0 part /
# Create new boot option
:~# efibootmgr --create --disk /dev/nvme0n1 --part 1 --label "Long Ubuntu Name" --loader \\EFI\\longubuntu\\shimx64.efi
享受:
现在重新启动。您仍应像以前一样启动到发行版。
如果没有,则启动到 USB 棒并安装 EFI 分区。然后撤消更改或复制回原始文件。在我的设备上,我像这样安装 EFI 分区:
:~# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
[...]
nvme0n1 259:0 0 238.5G 0 disk
├─nvme0n1p1 259:1 0 512M 0 part /boot/efi
└─nvme0n1p2 259:2 0 238G 0 part /
:~# mkdir -p /media/efi; mount /dev/nvme0n1p1 /media/efi