Come installare grub in un file .img?


26

Ho fatto quanto segue:

  1. creato un file .img vuoto con dd
  2. associato a / dev / loop0 con losetup
  3. creato una partizione in esso con fdisk
  4. formattato tale partizione con mke2fs
  5. copiato un sistema GNU / Linux personalizzato in quella partizione

Ora vorrei rendere avviabile il file .img installando grub nella sua directory MBR e / boot. Il mio obiettivo è caricare il file .img con qemu. Sarebbe meglio se grub2 fosse usato al posto di grub legacy.

Grazie.


Risposte:


24

Questo è con grub-pc versione 1.98 + 20100804-5ubuntu3 (Maverick Meerkat).

Il programma di installazione di grub2 può essere installato su dispositivi di loopback, ma se si monta utilizzando il mapper di dispositivo, si confonderà e si crederà di avere uno schema LVM, fallendo misteriosamente con un reclamo su un'astrazione mancante.

Invece, dovresti configurare tu stesso il dispositivo di loopback per la partizione, con un nome che deve corrispondere al modello "/ dev / loop [0-9]", cioè senza alcun designatore di partizione alla fine:

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

(Si noti che se si desidera che grub-mkconfig / update-grub funzioni su questo volume, il loopback della partizione deve essere collegato al loopback del disco in / dev e non direttamente al file di immagine).

Dato che hai usato fdisk per partizionare l'immagine, hai una tabella delle partizioni in stile msdos (nota anche come etichetta) e avviati usando un BIOS. Oltre a inserire stage1 / boot.img nell'MBR, stage1.5 / core.img verrà inserito in un'area di incorporamento nello spazio non partizionato (!) Che segue subito, e ci deve essere spazio per questo.

Il trucco è ora di dire al programma di installazione grub2 attraverso una mappa del dispositivo come la configurazione del loopback verrà mappata alle unità BIOS nella macchina virtuale. (In grub1 legacy questo è stato fatto direttamente nella shell). Probabilmente stai pianificando di avviare questa immagine come primo disco, quindi immagino che la mappatura appropriata sarebbe:

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

Qui ho inserito la mappa del dispositivo nell'immagine del disco guest, in modo da poter generare il file di configurazione di avvio grub.cfg:

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

(Attenzione che il post-installer del pacchetto grub-pc eseguirà un probe che sovrascrive la mappa del dispositivo (!), Quindi dovrai scriverlo dopo l' installazione ed eseguire tu stesso grub-mkconfig / update-grub).

Ora esegui il programma di installazione dall'host , indicando l'installazione guest:

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

Infine, smonta tutto ciò che è impostato qui prima di avviare qemu sulla tua immagine:

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

Wow! Ho appena incontrato la tua risposta mentre cercavo di capire perché non riuscivo ad aggiornare-grub un file di immagine, con loop di montaggio e chroot. Vedrò se questo può applicarsi al mio problema, ma questa è sicuramente una traccia interessante e merita molto il mio voto. Grazie!
filofel,

1
Bella risposta, sfortunatamente chroot /mnt grub-mkconfig -o /boot/grub/grub.cfgfallisce perché non c'è grub-mkconfignessun binario per quella materia nel disco .img ed /mntè già montato. Sarebbe bello se lo seguissi passo dopo passo e scrivessi tutti i dettagli / comandi.
Flavio

@RolKau: grazie per questa eccellente documentazione! Insieme alle modifiche apportate da Toh, ha risolto molti problemi che ho avuto per anni con grub durante l'integrazione in ambienti chroot.
Sparkie,

1
losetup -Pè un altro buon modo di montaggio di una singola partizione: stackoverflow.com/a/15200862/895245
Ciro Santilli新疆改造中心法轮功六四事件

Ricevo: /usr/sbin/grub-probe: warning: the device.map entry 'hd0,1' is invalid. Ignoring it. Please correct or delete your device.map.quindi questa risposta è inutile.
Calmarius,

11

grazie mille per queste spiegazioni. Ho integrato la tua soluzione nei miei script con le seguenti modifiche (tradotte nella tua notazione / variabili):

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

questo funziona almeno sulla compressione debian. Controlla '/boot/grub/grub.cfg' per la correttezza.


1
Dovrebbe cat > /mnt/boot/grub/device.mapessere fatto nell'ambiente chroot? In tal caso, il percorso dovrebbe essere /boot/grub/device.map.
cbliard,

0

Ecco una breve guida su come installare e avviare GRUB manualmente in un'immagine del disco QEMU. Non ho preso il passo successivo con un grub.cfg, ma presumo che sia piuttosto semplice una volta completata questa configurazione principale.

ipotesi:

  • 'grub-install --version' è "grub-install (GRUB) 2.02 ~ beta2-36ubuntu3.2"
  • 'qemu-system-x86_64 --version' è "Emulatore QEMU versione 2.5.0 (Debian 1: 2.5 + dfsg-5ubuntu10.6), Copyright (c) 2003-2008 Fabrice Bellard"
  • Un'immagine disco denominata "disk1" nella directory corrente
  • / dev / loop0 ha "Tipo Disklabel: dos" (cioè con fdisk)
  • / dev / loop0p1 è una partizione avviabile, già formattata con ext4

Ecco come ho avviato qemu nel menu di 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

Quindi viene visualizzata la shell GRUB:

                        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>

Se avessi copiato un kernel e un disco ram in / dev / loop0p1, potresti avviarlo:

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

Ed ecco la shell Linux predefinita (perché in questo caso no / sbin / init era disponibile)

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

    (initramfs)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.