Wie installiere ich grub in eine .img-Datei?


26

Ich habe folgendes gemacht:

  1. hat mit dd eine leere .img Datei erstellt
  2. verband es mit / dev / loop0 mit losetup
  3. habe mit fdisk eine Partition darin erstellt
  4. formatierte eine solche Partition mit mke2fs
  5. hat ein benutzerdefiniertes GNU / Linux-System in diese Partition kopiert

Jetzt möchte ich die IMG-Datei bootfähig machen, indem ich grub in das MBR- und / boot-Verzeichnis installiere. Mein Ziel ist es, die .img-Datei mit qemu zu laden. Es wäre besser, grub2 anstelle von grub legacy zu verwenden.

Vielen Dank.


Antworten:


24

Dies ist mit Grub-PC-Version 1.98 + 20100804-5ubuntu3 (Maverick Meerkat).

Das grub2-Installationsprogramm kann auf Loopback-Geräten installiert werden. Wenn Sie jedoch die Gerätezuordnung verwenden, wird dies verwirrt und Sie glauben, dass Sie ein LVM-Schema haben, das auf mysteriöse Weise mit einer Beschwerde über eine fehlende Abstraktion scheitert.

Stattdessen sollten Sie Setup das Loopback - Device für die Partition selbst, mit einem Namen, der muss mit dem Muster übereinstimmen „/ dev / loop [0-9]“, dh ohne Partition Bezeichner am Ende:

kpartx -v -a /dev/loop0
losetup /dev/loop1 /dev/mapper/loop0p1
mount /dev/loop1 /mnt

(Beachten Sie, dass, wenn grub-mkconfig / update-grub auf diesem Volume ausgeführt werden soll, der Partitions-Loopback mit dem Festplatten-Loopback unter / dev und nicht direkt mit der Image-Datei verbunden sein muss.)

Da Sie das Image mit fdisk partitioniert haben, verfügen Sie über eine Partitionstabelle im Stil von msdos (auch bekannt als label) und starten mit einem BIOS. Zusätzlich zum Einfügen der Datei stage1 / boot.img in den MBR wird die Datei stage1.5 / core.img unmittelbar danach in einen Einbettungsbereich in einem nicht partitionierten Bereich (!) Eingefügt. Dafür muss Platz vorhanden sein.

Der Trick besteht nun darin, dem grub2-Installationsprogramm über eine Gerätezuordnung mitzuteilen, wie Ihr Loopback-Setup den BIOS-Laufwerken in der virtuellen Maschine zugeordnet wird. (In grub1 Legacy wurde dies direkt in der Shell gemacht). Sie planen wahrscheinlich, dieses Image als erste Festplatte zu booten, daher würde die entsprechende Zuordnung lauten:

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

Hier habe ich die Gerätezuordnung in das Gastdatenträger-Image eingefügt, damit Sie die Startkonfigurationsdatei grub.cfg generieren können:

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

(Beachten Sie, dass der Post-Installer des grub-pc-Pakets einen Test ausführt , der die Gerätezuordnung (!) Überschreibt. Sie müssen ihn also nach der Installation schreiben und grub-mkconfig / update-grub selbst ausführen.)

Führen Sie nun das Installationsprogramm vom Host aus und verweisen Sie auf die Gastinstallation:

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

Zum Schluss hängen Sie alles, was Sie hier eingerichtet haben, aus, bevor Sie qemu auf Ihrem Image starten:

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

Wow! Ich bin gerade auf Ihre Antwort gestoßen, als ich versucht habe zu verstehen, warum ich eine Mount-Loop-Image-Datei mit Chroot nicht aktualisieren konnte. Ich werde sehen, ob dies auf mein Problem zutrifft, aber das ist definitiv ein interessanter Track und meine Zustimmung sehr wert. Vielen Dank!
Filofel

1
Schöne Antwort, chroot /mnt grub-mkconfig -o /boot/grub/grub.cfgscheitert leider , weil es keine grub-mkconfigoder keine Binärdatei für diese Angelegenheit in der .img-Disk gibt und /mntbereits gemountet ist. Es wäre großartig, wenn Sie Schritt für Schritt alle Details / Befehle schreiben würden.
Flavius

@RolKau: Danke für diese hervorragende Dokumentation! Zusammen mit den folgenden Modifikationen von toh löste es viele Probleme, die ich jahrelang mit grub hatte, als ich aus chroot-Umgebungen einbettete.
Sparkie

1
losetup -Pist eine weitere gute Möglichkeit, eine einzelne Partition zu mounten
Ciro Santilli Am

Ich bekomme: /usr/sbin/grub-probe: warning: the device.map entry 'hd0,1' is invalid. Ignoring it. Please correct or delete your device.map.Also diese Antwort ist nutzlos.
Calmarius

11

Vielen Dank für diese Erklärungen. Ich habe Ihre Lösung mit folgenden Änderungen (übersetzt in Ihre Notation / Variablen) in meine eigenen Skripte integriert:

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

das funktioniert zumindest bei debian squeeze. Überprüfen Sie die Datei '/boot/grub/grub.cfg' auf Richtigkeit.


1
Sollte cat > /mnt/boot/grub/device.mapin der Chroot-Umgebung erfolgen? Wenn ja, sollte der Pfad sein /boot/grub/device.map.
Cbliard

0

Hier finden Sie eine kurze Anleitung zum manuellen Installieren und Booten von GRUB in ein QEMU-Image. Ich habe es nicht mit einer grub.cfg zum nächsten Schritt gebracht, aber ich gehe davon aus, dass dies ziemlich einfach ist, sobald dieses Haupt-Setup abgeschlossen ist.

Annahmen:

  • 'grub-install --version' ist "grub-install (GRUB) 2.02 ~ beta2-36ubuntu3.2"
  • "qemu-system-x86_64 --version" ist "QEMU-Emulator Version 2.5.0 (Debian 1: 2.5 + dfsg-5ubuntu10.6), Copyright (c) 2003-2008 Fabrice Bellard".
  • Ein Disk-Image mit dem Namen "disk1" im aktuellen Verzeichnis
  • / dev / loop0 hat "Disklabel type: dos" (dh mit fdisk)
  • / dev / loop0p1 ist eine bootfähige Partition, die bereits mit ext4 formatiert wurde

So habe ich qemu in das GRUB-Menü gebootet:

    # 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

Dann erscheint die 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>

Wenn Sie einen Kernel und eine RAM-Festplatte nach / dev / loop0p1 kopiert haben, können Sie es booten:

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

Und hier ist die Standard-Linux-Shell (da in diesem Fall kein / sbin / init verfügbar war)

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

    (initramfs)
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.