我想让grub1和GPT一起工作。目前在虚拟机上,作为迁移真正的虚拟机之前的一个测试步骤。
我为/boot创建了一个分区,并创建了一个不同的分区,我希望在其中嵌入GRUBstage1.5。这是gdisk为GPT分区表显示的内容:
Number Start (sector) End (sector) Size Code Name
1 2048 104447 50.0 MiB 8300 boot
2 104448 206847 50.0 MiB EF00 EFI
3 206848 16984063 8.0 GiB 8E00
4 1024 2047 512.0 KiB EF02 GRUB1不要费心于EFI分区,在这个场景中不使用它。只是我打算稍后将系统升级到UEFI (我知道,对grub1说再见),并希望更早地创建分区。
现在,由于grub1不了解GPT,我创建了一个混合MBR,包含第1和第4分区。这就是gdisk对混合MBR的看法:
Number Boot Start Sector End Sector Status Code
1 1 1023 primary 0xEE
2 * 2048 104447 primary 0x83
3 1024 2047 primary 0xEF
4 104448 20971519 primary 0xEE我的目的是将stage1.5放在小于1MB的小分区上,并在boot分区(GPT 1/MBR 2)上拥有真正的引导分区(包括D3、grub配置和内核映像)。但是,我不能让grub安装这个舞台。
运行grub时,命令find /grub/menu.lst向我显示(hd0,0),因此看起来它使用的是正在运行的内核分区布局,其中嵌入分区将是(hd0,3)。无论如何给予root (hd0,3)给我
文件系统类型未知,分区类型0x83
文件系统类型并不奇怪,因为分区是空的,但是我已经设置了分区类型,并且它是不可见的。
当我尝试将stage1.5嵌入到分区中时(使用embed (hd0,0)/grub/e2fs_stage1_5 (hd0,3),我得到了一个错误:
错误17:无法挂载选定的分区
我尝试在该分区上创建reiserfs3 (因为reiserfs3有16 is的空间用于嵌入引导加载器),但是错误是相同的。但是,我创建的FS是一个非标准的FS,在一个单独的设备上有日志,因为512 to不足以创建一个正常的FS。
我已经检查过(hd0,3)是正确的驱动器,因为向分区的第一个扇区写入一些东西并在grub中运行cat (hd0,3)+1会给出预期的输出。
关于如何运行这个选项还有其他的选择吗?我正在考虑手动将stage1.5嵌入到选定的分区(cat /boot/grub/e2fs_stage1_5 > /dev/sda4)中,并正确地修改它(我猜这只是第一扇区的区块列表和第二扇区的stage2位置),然后从那里开始,但我想让它正常工作。
我使用的版本是来自Gentoo的sys-boot/grub-0.97-r18。
发布于 2018-11-19 23:04:16
结果却比预期的更容易也更难。
首先,Gentoo (以及据我所知的许多其他发行版)已经修补了Grub以便能够读取GPT,因此不需要使用混合MBR的整个麻烦,它可以使用纯GPT。
这更容易,因为标准setup (hd0,0)确实可以工作,比如“生成一个可引导的系统”。然而,按照我的标准,这个系统还不够健壮--因为setup无法在任何地方嵌入第1.5级,所以它需要修补stage2并将其位置包含在MBR中的磁盘上。因此,如果有什么东西移动stage2,改变以前的块,我就会得到一个无法引导的系统。更糟糕的是,我可能不会首先注意到这一点--一次升级将stage2移至不同的位置,但旧的则保持原样。系统还在启动,我什么也没注意到。但是,由于引导期间使用的代码现在是文件系统的POV中的空闲空间,所以后来有一些东西随机地覆盖了它并砰地一声。
因此,我采用了问题末尾概述的步骤,手动嵌入第1.5阶段。
首先,创建一个适当的stage1.5文件的副本,并在该副本上启动一个十六进制编辑器。如果您没有现成的工具,我已经成功地使用了vim和xxd -编辑文件,输入:!xxd编辑文件为十六进制,键入:!xxd -r并保存。文件在结束时会得到一个额外的行提要,但它是无害的。注意,在这种情况下,右侧的ASCII部分被完全忽略,只使用十六进制数字。您需要编辑该文件中的三项内容:
0xf8处,第1.5级将嵌入其中。请注意,它是小端点,并且相对于磁盘的启动。由于BIOS引导分区从扇区1024开始,这是1025,或0x0401或(以小字节为单位)字节0104。0x1fc。因为我的第1.5阶段是9908字节(9909加上额外的换行符),它是20个扇区(19个扇区是19*512=9728,20个扇区是10240字节),所以我需要放19个,或者十六进制13。ff更改为00。不要碰附近的ff's。下面是原始文件和修改文件的不同之处:
-000001f0 00 00 00 00 00 00 00 00 02 00 00 00 00 00 20 02 |.............. .|
+000001f0 00 00 00 00 00 00 00 00 01 04 00 00 13 00 20 02 |.............. .|
00000200 ea 70 22 00 00 00 03 02 ff ff ff 00 00 00 00 00 |.p".............|
-00000210 02 00 30 2e 39 37 00 ff ff ff ff 2f 62 6f 6f 74 |..0.97...../boot|
+00000210 02 00 30 2e 39 37 00 ff ff 00 ff 2f 62 6f 6f 74 |..0.97...../boot|它的工作方式是,第一个阶段1.5的第一个扇区从它的末尾读取数字,并从磁盘开始时从指定的一个扇区开始读取许多扇区。这会将第1.5阶段的其余扇区加载到内存中,然后执行它们。第三部分实际上是stage2在磁盘上的位置,grub需要在其中找到正确的分区。如果您感兴趣的话,相关代码是grub源代码中的stage2/disk_io.c,请记住,您在#ifdef STAGE1_5中使用了该部分,加载其余部分的第一个扇区在stage2/start.S中。也许可以在几个不连续的部分中使用第1.5阶段,但我还没有尝试过。
编写修改后的第1.5阶段后,只需根据您的喜好使用cat或dd将其复制到目标分区(我的示例中的第四个分区)。
最后,在grub中执行
install /boot/grub/stage1 (hd0) (hd0)1024+20使用(hd0)作为正在使用的设备的grub名称,1024是嵌入式阶段1.5(顺便说一句,BIOS启动分区的启动)的开始,20是第1.5级块的大小。这就完成了这个过程。
https://unix.stackexchange.com/questions/478247
复制相似问题