如何将grub安装到.img文件中?


26

我做了以下事情:

  1. 用dd创建了一个空的.img文件
  2. 将其与lostup关联到/ dev / loop0
  3. 用fdisk在其中创建了一个分区
  4. 用mke2fs格式化这样的分区
  5. 将自定义GNU / Linux系统复制到该分区

现在,我想通过将grub安装到其MBR和/ boot目录中来使.img文件可启动。我的目标是用qemu加载.img文件。如果使用grub2代替grub遗留会更好。

谢谢。


Answers:


24

这与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

(请注意,如果要让grub-mkconfig / update-grub在此卷上运行,则分区环回必须连接到/ dev下的磁盘环回,而不是直接连接到映像文件)。

由于使用fdisk对映像进行分区,因此具有msdos样式的分区表(也称为标签),并使用BIOS进行引导。除了将stage1 / boot.img放在MBR中之外,stage1.5 / core.img也将紧随其后放在未分区空间(!)中的嵌入区域中,并且必须有空间。

现在,诀窍是通过设备映射告诉grub2安装程序,您的环回设置将如何映射到虚拟机中的BIOS驱动器。(在grub1旧版中,这是直接在Shell中完成的)。您可能打算将该映像作为第一个磁盘引导,因此我想适当的映射应为:

mkdir -p /mnt/boot/grub
cat > /mnt/boot/grub/device.map <<EOF
(hd0)   /dev/loop0
(hd0,1) /dev/loop1
EOF

在这里,我已将设备映射放入来宾磁盘映像中,以便可以生成引导配置文件grub.cfg:

mount --bind /dev /mnt/dev
chroot /mnt grub-mkconfig -o /boot/grub/grub.cfg

(请注意,grub-pc软件包的后安装程序将运行覆盖设备映射(!)的探针,因此您必须安装编写它并自己运行grub-mkconfig / update-grub。)

现在从主机运行安装程序,指向来宾安装:

grub-install --no-floppy --grub-mkdevicemap=/mnt/boot/grub/device.map --root-directory=/mnt /dev/loop0

最后,在映像上启动qemu之前,先卸载此处设置的所有内容:

umount /mnt/dev
umount /mnt
losetup -d /dev/loop1
kpartx -v -d /dev/loop0

哇!我只是在试图理解为什么我无法更新grub装入循环的chroot映像文件时遇到了您的答案。我将看看这是否可以解决我的问题,但这绝对是一条有趣的路线,非常值得我赞扬。谢谢!
filofel 2010年

1
好的答案,很遗憾chroot /mnt grub-mkconfig -o /boot/grub/grub.cfg失败,因为grub-mkconfig.img磁盘中没有与此相关的二进制文件,并且/mnt已经挂载了。如果您一步一步地编写所有详细信息/命令,那将是很好的。
Flavius 2012年

@RolKau:感谢您提供的出色文档!连同下面的toh的修改一起,解决了我多年以来在chroot环境中嵌入grub时遇到的许多问题。
sparkie 2013年

1
losetup -P是安装单个分区的另一种好方法:stackoverflow.com/a/15200862/895245
Ciro Santilli新疆改造中心法轮功六四事件

我得到:/usr/sbin/grub-probe: warning: the device.map entry 'hd0,1' is invalid. Ignoring it. Please correct or delete your device.map.所以这个答案是没有用的。
Calmarius

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

这至少对debian压缩有效。检查“ /boot/grub/grub.cfg”的正确性。


1
应该cat > /mnt/boot/grub/device.map在chroot环境中完成吗?如果是这样,则路径应为/boot/grub/device.map
cbliard 2014年

0

这是有关如何手动将GRUB手动安装和引导到QEMU磁盘映像的快速演练。我尚未使用grub.cfg进行下一步,但是我认为一旦完成此主要设置,这将非常简单。

假设:

  • “ grub-install --version”是“ grub-install(GRUB)2.02〜beta2-36ubuntu3.2”
  • “ qemu-system-x86_64 --version”是“ QEMU仿真器版本2.5.0(Debian 1:2.5 + dfsg-5ubuntu10.6),版权所有(c)2003-2008 Fabrice Bellard”
  • 当前目录中名为“ disk1”的磁盘映像
  • / dev / loop0具有“ Disklabel type:dos”(即使用fdisk)
  • / dev / loop0p1是可引导分区,已使用ext4格式化

这是我将qemu引导到GRUB菜单的方式:

    # losetup -fP disk1
    # ls /dev/loop0*
    /dev/loop0  /dev/loop0p1  /dev/loop0p2  /dev/loop0p3
    # mount /dev/loop0p1 /mnt
    # cat > loop0device.map <<EOF
    (hd0) /dev/loop0
    EOF
    # grub-install --no-floppy --grub-mkdevicemap=loop0device.map \
    --modules="part_msdos" --boot-directory=/mnt /dev/loop0 -v
    # umount /mnt
    # losetup -d /dev/loop0
    # qemu-system-x86_64 -m 512 -curses -hda disk1 -enable-kvm

然后出现GRUB shell:

                        GNU GRUB  version 2.02~beta2-36ubuntu3.2

       Minimal BASH-like line editing is supported. For the first word, TAB
       lists possible command completions. Anywhere else TAB lists possible
       device or file completions.


    grub> ls
    (hd0) (hd0,msdos3) (hd0,msdos2) (hd0,msdos1) (fd0)
    grub>

如果已将内核和ram磁盘复制到/ dev / loop0p1,则可以引导它:

    grub> linux (hd0,msdos1)/vmlinuz
    grub> initrd (hd0,msdos1)/initrd
    grub> boot

这是默认的Linux shell(因为在这种情况下没有/ sbin / init可用)

    BusyBox v1.22.1 (Ubuntu 1:1.22.0-15ubuntu1) built-in shell (ash)
    Enter 'help' for a list of built-in commands.

    (initramfs)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.