我做了以下事情:
现在我想通过将 grub 安装到其 MBR 和 /boot 目录中来使 .img 文件可启动。我的目标是使用 qemu 加载 .img 文件。如果使用 grub2 而不是 grub legacy 会更好。
谢谢。
小智 25
这是 grub-pc 版本 1.98+20100804-5ubuntu3 (Maverick Meerkat)。
grub2 安装程序可以安装到环回设备,但是如果您使用设备映射器进行安装,它会感到困惑并相信您有一个 LVM 方案,神秘地失败并抱怨缺少抽象。
相反,您应该自己为分区设置环回设备,名称必须与模式“/dev/loop[0-9]”匹配,即末尾没有任何分区指示符:
kpartx -v -a /dev/loop0
losetup /dev/loop1 /dev/mapper/loop0p1
mount /dev/loop1 /mnt
Run Code Online (Sandbox Code Playgroud)
(注意,如果想让grub-mkconfig/update-grub对这个卷进行操作,那么分区环回必须连接到/dev下的磁盘环回,而不是直接连接到镜像文件)。
由于您使用 fdisk 对映像进行分区,因此您有一个msdos样式的分区表(又名标签),并使用 BIOS 启动。除了将stage1/boot.img放入MBR之外,stage1.5/core.img会被放入紧随其后的未分区空间(!)的embedding区域,并且必须有空间。
现在的技巧是通过设备映射告诉 grub2 安装程序您的环回设置将如何映射到虚拟机中的 BIOS 驱动器。(在 grub1 legacy 中,这是直接在 shell 中完成的)。您可能打算将此映像作为第一个磁盘启动,因此我想适当的映射是:
mkdir -p /mnt/boot/grub
cat > /mnt/boot/grub/device.map <<EOF
(hd0) /dev/loop0
(hd0,1) /dev/loop1
EOF
Run Code Online (Sandbox Code Playgroud)
这里我把设备映射放在了guest磁盘镜像中,这样就可以生成启动配置文件grub.cfg:
mount --bind /dev /mnt/dev
chroot /mnt grub-mkconfig -o /boot/grub/grub.cfg
Run Code Online (Sandbox Code Playgroud)
(请注意,grub-pc 软件包的后安装程序将运行覆盖设备映射(!)的探针,因此您必须在安装后编写它并自己运行 grub-mkconfig/update-grub)。
现在从主机运行安装程序,指向来宾安装:
grub-install --no-floppy --grub-mkdevicemap=/mnt/boot/grub/device.map --root-directory=/mnt /dev/loop0
Run Code Online (Sandbox Code Playgroud)
最后,在您的镜像上启动 qemu 之前卸载这里设置的所有内容:
umount /mnt/dev
umount /mnt
losetup -d /dev/loop1
kpartx -v -d /dev/loop0
Run Code Online (Sandbox Code Playgroud)
小智 11
非常感谢这些解释。我通过以下修改将您的解决方案集成到我自己的脚本中(转换为您的符号/变量):
modprobe dm_mod
kpartx -va /root/rootfs.img # *.img is setup elsewhere
# normally you now would mount /dev/loop0p1 directly. BUT
# grub specialists didn't manage to work with loop partitions other than /dev/loop[0-9]
losetup -v -f --show /dev/mapper/loop0p1
mount /dev/loop1 /mnt
mkdir -p /mnt/boot/grub
# change into chrooted environment. all remaining work will be done from here. this differs from the howto above.
LANG=C chroot /mnt /bin/bash
set -o vi
mount -t sysfs sysfs /sys
mount -t proc proc /proc
# avoid grub asking questions
cat << ! | debconf-set-selections -v
grub2 grub2/linux_cmdline select
grub2 grub2/linux_cmdline_default select
grub-pc grub-pc/install_devices_empty select yes
grub-pc grub-pc/install_devices select
!
apt-get -y install grub-pc
# don't setup device.map prior to this point. It will be overwritten by grub-pc install
#corrected the /mnt/boot/grub/device.map to /boot/grub/device.map
cat > /boot/grub/device.map << !
(hd0) /dev/loop0
(hd0,1) /dev/loop1
!
# install here to fill /boot/grub for grub-mkconfig (update-grub)
grub-install /dev/loop0
# generate /boot/grub/grub.cfg
update-grub
Run Code Online (Sandbox Code Playgroud)
这至少适用于 debian 挤压。检查“/boot/grub/grub.cfg”是否正确。