基本工作系统细节:
我使用 Ubuntu 12.04 服务器 CD 来安装服务器。
我有 4 个磁盘。在所有磁盘上我执行了以下操作,类似于本指南:
- 创建了 2GB 的交换分区
- 创建了 256 GB 的 /boot 分区
- 创建一个 64 GB 的 RAID10 分区(用于根目录)
- 创建一个大的 RAID10 分区,占用剩余空间
我将启动盘格式化为 ext3。我在根分区和大分区上设置了 RAID10。我将根分区格式化为 ext4。我在大分区上创建了一个逻辑卷,并将其格式化为 ext4。
最终系统运行良好,并且启动正常。
问题详情:
然后我决定记录一个失败的过程。第一步,我决定重新安装 grub。
# grub-install /dev/sda
warn: This GPT partition label has no BIOS Boot Partition; embedding won't be possible!.
error: Embedding is not possible. GRUB can only be installed in this setup by using blocklists. However, blocklists are UNRELIABLE and their use is discouraged..
# grub-install /dev/sdb
warn: This GPT partition label has no BIOS Boot Partition; embedding won't be possible!.
error: Embedding is not possible. GRUB can only be installed in this setup by using blocklists. However, blocklists are UNRELIABLE and their use is discouraged..
所以看起来它失败了,但也似乎放弃了并且没有做出任何改变。所以我重新启动了。启动失败了。它只是挂起,黑屏,光标闪烁,大约 4 行。如果我按住“Shift”启动,我会在光标左侧看到“GRUB”字样,但没有交互提示。
此时,我使用啟動修復磁碟生成此报告: http://paste.ubuntu.com/966531/
请注意,在上述报告中,它表示引导加载程序未指向 core.img 的正确扇区。(sda 是虚拟 cd;sdb 是启动盘;sdc 是 sdb 的镜像,但启动不是镜像,只有一个单独的不相关分区并格式化为 ext3;sdd 和 sde 有启动空间但未格式化)
然后我从 Ubuntu 服务器 CD 启动,启动救援系统,并发出以下命令,这些命令没有错误地完成(其中 sda 是虚拟 CD,b、c、d、e 是前面 grub 命令中的 a、b、c、d 磁盘):
# parted /dev/sdb set 2 bios_grub on
# parted /dev/sdc set 2 bios_grub on
# grub-install /dev/sdb
# grub-install /dev/sdc
此时,我使用啟動修復磁碟生成此报告: http://paste.ubuntu.com/966561/
请注意,在上面的报告中,有关 core.img 的问题已经消失。它似乎指向了正确的扇区。
现在,如果我尝试启动,我会得到一个 grub 提示符。如果我运行“set”,我会看到找到并设置了 root。如果我运行“ls /”,我会看到来自 raid 卷的 root 目录,包括 vmlinuz 内核文件。如果我输入“ls /vmlinuz”,它会显示“错误:未找到文件”。如果我使用“linux”命令尝试加载内核,它会显示相同的错误。如果我使用“ls -l /”,则不会列出 vmlinuz 文件。
过于详细的细节,如果你想遵循:
我注意到也没有 /boot/grub/grub.cfg,所以我运行
# grub-mkconfig -o /boot/grub/grub.cfg
但问题依然存在。
如果我使用“gptsync”工具,此行为不会发生任何变化。
启动修复盘无法修复系统,因为它要求我使用启用了 EFI 的 BIOS 启动。我简单研究了一下,但不知道它是如何工作的。我在启动选项中找到了 UEFI shell,但我对它一无所知,也不知道如何从那里更改启动(例如从该 EFI shell 启动 CD)。
我也读过这一页,但 Ubuntu 没有附带“grub”命令,所以我无法完全遵循它。我可以简单地安装该命令,但我更想知道 Ubuntu 安装程序是如何安装它的,而不是使用不同的设置。它使用了阻止列表吗?
以下是在以下计算机上启动 parted 时的输出:啟動修復磁碟(其中 sdb 是第一个硬盘,从磁盘启动时为 sda,并且在第二个粘贴链接中“boot”更改为“bios_grub”):
Model: ATA Hitachi HUA72303 (scsi)
Disk /dev/sdb: 3001GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Number Start End Size File system Name Flags
1 17.4kB 2000MB 2000MB linux-swap(v1) swap1
2 2000MB 2256MB 256MB ext3 boot1 boot (this says bios_grub in 2nd link)
3 2256MB 66.3GB 64.0GB root1 raid
4 66.3GB 3001GB 2934GB data1 raid
这里有一个不相关的超旧虚拟机用于比较(对于不熟悉啟動修復磁碟): http://paste.ubuntu.com/966799/
这是运行上述 grub-mkconfig 并将“bios_grub”重新设置为“boot”后,来自问题系统的最新粘贴。 http://paste.ubuntu.com/966808/
比较两者,这看起来很有趣:
sdb2: __________________________________________________________________________
File system:
Boot sector type: Grub2's core.img
Boot sector info:
Mounting failed: mount: unknown filesystem type ''
md/bcserver8:0: ________________________________________________________________
File system: ext4
Boot sector type: -
Boot sector info:
Operating System: Ubuntu 12.04 LTS
Boot files: /boot/grub/grub.cfg /etc/fstab /boot/grub/core.img
看起来 raid 有启动文件,而 sdb2 未格式化。(尽管如此,系统在运行 grub-install 之前启动了)。从救援 CD 中,“mount -t ext3 /dev/sdb2 /boot”失败。但这会造成混淆是有道理的,因为 grub 明确使用分区 2(设置 bios_grub 的 parted 命令中的 2)。
所以我做了这样的事情:
# mkfs.ext3 -L boot1 /dev/sdb2
# mv boot boot_on_root
# mkdir boot
# mount /dev/sdb2 boot
# rsync -avHP boot_on_root/ boot/
# parted /dev/sdb set 2 bios_grub on
# parted /dev/sdc set 2 bios_grub on
# grub-install /dev/sdb
# grub-install /dev/sdc
然后重新启动,屏幕又变黑了,没有提示。 http://paste.ubuntu.com/966848/
因此,此时,我的猜测是,当设置 bios_grub 时,grub 不会安装到 MBR,也不会安装到 ext3 上的 ext3 文件系统,而是安装到分区本身,就好像它是 EFI 一样……这显然会弄乱那里的 ext3 文件系统。而且从我对 EFI 的简要阅读来看,听起来 EFI 假设第一个分区是启动分区,但在我的例子中,第一个是交换分区,而且它应该是 FAT,而不是无法安装的东西……所以因为这几乎没有意义,我仍然完全迷失了方向,没有任何线索。[编辑:现在我有线索了……跳到下面一点进行更新]
现在当我点击修复啟動修復磁碟,它询问其他内容。上次错误隐藏在窗口下,我不得不将另一个窗口拖走才能看到它。这次主窗口不见了,新窗口显示:
GPT detected. You may want to retry after creating a
BIOS-Boot partition (>1Mo, flag). Do you want to continue?
于是我点击了“是”,它说修复成功,并创建了另一个粘贴: http://paste.ubuntu.com/966862/
但屏幕仍然黑着,光标还在闪烁。
现在我的理论是,引导被非胖非 EFI 的东西覆盖了,这只是 grub 代码,否则它之前应该位于扇区 0-63 中。幸运的是,我在这个页面上遇到了一个非常清晰的声明,这可能让我完全理解了这一切的含义。然后在我发现这一点之后,Jeremy 发布了一条答案,如果属实,则证实这是缺失的关键概念。 http://blog.psych0tik.net/2011/08/grub-embedding-blocklists-and-bios_grub-partitions/
问题:
发生了什么事?为什么 grub 无法启动?为什么显示“文件未找到”?
为什么没有使用 parted 设置的这个设置(Ubuntu 安装程序没有设置)grub 就无法安装?我以为我需要安装的只是一个不在 LVM 也不在软件 RAID 中的单独 /boot,因为我的根目录在 RAID 中,分区表是 GPT。
Ubuntu CD 安装程序如何安装它而不会出现此问题,并且没有 bios_grub 设置?
我也会考虑使用 EFI。如果这是一个好主意,并且有标准的设置方法,我随时都愿意学习新东西。
最快能让我高兴的答案(即使没有回答我所有的问题)是一组命令,我可以从救援 CD 运行这些命令,以与安装 CD 相同的方式修复引导加载程序。如果我可以使用启动系统而不是 CD 来运行它们,那就太好了。
答案1
解决方案是使用 bios_grub 分区,它与 /boot 分区不同。
默认情况下,bios_grub 分区为 1MiB,并且必须标记为 bios_grub。我的分区是我磁盘上的第一个分区。如果您的分区 2 实际上是 parted 所建议的 /boot,那么这是不正确的,您应该再创建 1MiB 分区。
使用 GPT 和 GRUB2,最小文件系统有三个分区:bios_grub、root、swap。(不完全确定是否需要 swap)
为什么简单运行“grub-install”后 grub 无法启动?
未知...如果它明确说明无法嵌入因此无法工作,您会认为它不会修改任何东西。
为什么显示“未找到文件”?
/vmlinuz 是使用启动分区的符号链接,而启动分区已损坏。bios_grub 代码是在其 ext3 结构之上编写的。这可能意味着 /boot 未挂载,并且在那里看到的 grub 文件实际上位于根系统上,而根系统不包含内核。
为什么没有使用 parted 设置的这个设置,grub 就无法安装
与 MBR 不同,GPT 分区表没有空间用于引导加载程序。因此必须创建一个特定分区来保存引导代码。在运行“grub-install”之前,请使用以下命令指定此分区:
parted /dev/sda set 1 bios_grub on
我以为我需要的只是一个单独的 /boot。Ubuntu CD 安装程序如何在没有 bios_grub 设置的情况下安装它?
这个要求似乎是 Ubuntu 安装程序所需要的全部内容,但它创建了一个很容易损坏的非标准系统。
当 GRUB 说“此 GPT 分区标签没有BIOS 启动分区",它的意思是 bios_grub 分区,而不是 /boot。