Comment installer grub dans un fichier .img?

26

J'ai fait ce qui suit:

  1. créé un fichier .img vide avec dd
  2. l'a associé à / dev / loop0 avec losetup
  3. créé une partition avec fdisk
  4. formaté cette partition avec mke2fs
  5. copié un système GNU / Linux personnalisé dans cette partition

Maintenant, j'aimerais rendre le fichier .img amorçable en installant grub dans ses répertoires MBR et / boot. Mon objectif est de charger le fichier .img avec qemu. Il serait préférable d’utiliser Grub2 au lieu de Grub Legacy.

Merci.

Francesco Turco
la source
unix.stackexchange.com/questions/163791/…
Ciro Santilli publié par 996ICU le

Réponses:

24

Ceci est avec la version 1.98 + 20100804-5ubuntu3 (Maverick Meerkat).

Le programme d’installation de grub2 peut s’installer sur des périphériques en boucle, mais si vous montez à l’aide du mappeur de périphériques, vous serez confus et croirez que vous avez un schéma LVM, échouant mystérieusement avec une réclamation concernant une abstraction manquante.

Au lieu de cela, vous devez configurer vous-même le périphérique de bouclage pour la partition, avec un nom qui doit correspondre au modèle "/ dev / loop [0-9]", c'est-à-dire sans aucun indicateur de partition à la fin:

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

(Notez que si vous souhaitez que grub-mkconfig / update-grub fonctionne sur ce volume, le bouclage de partition doit être connecté au bouclage de disque sous / dev et non directement au fichier image).

Puisque vous avez utilisé fdisk pour partitionner l’image, vous disposez d’une table de partition de type msdos (aka label) et démarrez à l’aide d’un BIOS. En plus de placer le stage1 / boot.img dans le MBR, le stage1.5 / core.img sera placé dans une zone d'intégration dans un espace non partitionné (!) Juste après, et il doit y avoir un espace pour cela.

L'astuce consiste maintenant à indiquer au programme d'installation grub2, via une carte de périphérique, comment votre configuration de bouclage sera mappée sur les lecteurs BIOS de la machine virtuelle. (Dans Grub1, cela se faisait directement dans la coque). Vous envisagez probablement de démarrer cette image en tant que premier disque. Par conséquent, le mappage approprié serait le suivant:

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

Ici, j'ai placé la carte des périphériques dans l'image du disque invité, de sorte que vous puissiez générer le fichier de configuration de démarrage grub.cfg:

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

(Attention, le post-installateur du paquet grub-pc lancera une sonde qui écrasera la carte des périphériques (!). Vous devrez donc l'écrire après l' installation et exécuter vous-même grub-mkconfig / update-grub).

Maintenant, lancez le programme d'installation à partir de l' hôte , en pointant sur l'installation du client:

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

Enfin, démontez tout ce qui est configuré ici avant de lancer qemu sur votre image:

umount /mnt/dev
umount /mnt
losetup -d /dev/loop1
kpartx -v -d /dev/loop0
RolKau
la source
Hou la la! Je viens de rencontrer votre réponse en essayant de comprendre pourquoi je ne pouvais pas mettre à jour grub un fichier image chrooté en boucle de montage. Je vais voir si cela peut s’appliquer à mon problème, mais c’est vraiment une piste intéressante et qui vaut vraiment la peine d’être ma voix positive. Merci!
Filofel
1
Bonne réponse, chroot /mnt grub-mkconfig -o /boot/grub/grub.cfgéchoue malheureusement car il n'y a pas grub-mkconfigou aucun binaire dans le disque .img, et /mntest déjà monté. Ce serait formidable si vous avançiez pas à pas et écriviez tous les détails / commandes.
Flavius
@RolKau: merci pour cette excellente documentation! Avec les modifications de toh ci-dessous, il a résolu de nombreux problèmes que je rencontrais depuis des années avec grub lors de l'intégration dans des environnements chrootés.
sparkie
1
losetup -Pest un autre bon moyen de monter une seule partition: stackoverflow.com/a/15200862/895245
Ciro Santilli Cliquez ici pour afficher le code promo 996ICU le
Je comprends: /usr/sbin/grub-probe: warning: the device.map entry 'hd0,1' is invalid. Ignoring it. Please correct or delete your device.map.cette réponse est donc inutile.
Calmarius
11

merci beaucoup pour ces explications. J'ai intégré votre solution dans mes propres scripts avec les modifications suivantes (traduites en notation / variables):

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

cela fonctionne au moins sur Debian Squeeze. Vérifiez '/boot/grub/grub.cfg' pour l'exactitude.

toh
la source
1
Devrait cat > /mnt/boot/grub/device.mapêtre fait dans l'environnement chrooté? Si oui, le chemin devrait être /boot/grub/device.map.
cbliard
0

Voici un aperçu de la procédure d'installation et de démarrage manuel de GRUB dans une image disque QEMU. Je n'ai pas passé à l'étape suivante avec un fichier grub.cfg, mais je suppose que c'est assez simple une fois que cette configuration principale est terminée.

Hypothèses:

  • 'grub-install --version' est "grub-install (GRUB) 2.02 ~ beta2-36ubuntu3.2"
  • 'qemu-system-x86_64 --version' est "Émulateur QEMU version 2.5.0 (Debian 1: 2.5 + dfsg-5ubuntu10.6), Copyright (c) 2003-2008 Fabrice Bellard"
  • Une image disque nommée "disk1" dans le répertoire en cours
  • / dev / loop0 a "Type de label: dos" (c'est-à-dire avec fdisk)
  • / dev / loop0p1 est une partition amorçable, déjà formatée avec ext4

Voici comment j'ai lancé qemu dans le menu 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

Ensuite, le shell GRUB apparaît:

                        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>

Si vous aviez copié un noyau et un disque virtuel dans / dev / loop0p1, vous pouvez l’amorcer:

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

Et voici le shell Linux par défaut (car aucun / sbin / init n'était disponible dans ce cas)

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

    (initramfs)
Beau Harder
la source