Como instalar o grub em um arquivo .img?

23

Eu fiz o seguinte:

  1. criou um arquivo .img vazio com dd
  2. associou-o a / dev / loop0 com losetup
  3. criou uma partição nele com fdisk
  4. formatou essa partição com mke2fs
  5. copiou um sistema GNU / Linux personalizado para essa partição

Agora eu gostaria de fazer o arquivo .img inicializável instalando o grub em seu diretório MBR e / boot. Meu objetivo é carregar o arquivo .img com o qemu. Seria melhor se o grub2 fosse usado em vez do legado do grub.

Obrigado.

    
por Francesco Turco 14.04.2010 / 20:03

3 respostas

22

Isto é feito com a versão 1.98 + 20100804-5ubuntu3 do grub-pc (Maverick Meerkat).

O instalador do grub2 pode ser instalado em dispositivos loopback, mas se você montar usando o mapeador de dispositivos, ele ficará confuso e acreditará que você tem um esquema LVM, falhando misteriosamente com uma reclamação sobre uma abstração ausente.

Em vez disso, você deve configurar o dispositivo de loopback para a partição, com um nome que deve corresponder ao padrão "/ dev / loop [0-9]", ou seja, sem qualquer designador de partição no end:

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

(Note que se você quiser que o grub-mkconfig / update-grub opere neste volume, em seguida, o loopback de partição deve ser conectado ao loopback do disco em / dev e não diretamente para o arquivo de imagem).

Como você usou o fdisk para particionar a imagem, você tem uma tabela de partições no estilo msdos (também conhecida como label) e inicializa usando um BIOS. Além de colocar o stage1 / boot.img no MBR, o stage1.5 / core.img será colocado em uma área de incorporação no espaço não particionado (!) Logo após, e deve haver espaço para isso.

O truque agora é dizer ao instalador do grub2 através de um mapa de dispositivos como a configuração de loopback será mapeada para as unidades BIOS na máquina virtual. (No legado grub1 isso foi feito diretamente no shell). Você provavelmente está planejando inicializar essa imagem como o primeiro disco, então acho que o mapeamento apropriado seria:

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

Aqui eu coloquei o mapa de dispositivos dentro da imagem de disco do convidado, para que você possa gerar o arquivo de configuração de inicialização grub.cfg:

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

(Cuidado que o pós-instalador do pacote grub-pc executará teste que sobrescreve o mapa do dispositivo (!), então você terá que escrevê-lo após a instalação e executar o grub-mkconfig / update-grub você mesmo.

Agora, execute o instalador a partir do host , apontando para a instalação do convidado:

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

Por fim, desmonte tudo configurado aqui antes de iniciar o qemu na sua imagem:

umount /mnt/dev
umount /mnt
losetup -d /dev/loop1
kpartx -v -d /dev/loop0
    
por 17.10.2010 / 20:48
10

muito obrigado por essas explicações. Eu integrei sua solução em meus próprios scripts com as seguintes modificações (traduzidas para sua notação / variáveis):

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

isso funciona pelo menos no debian squeeze. Verifique '/boot/grub/grub.cfg' para correção.

    
por 31.12.2012 / 17:56
0

Here's a quick walk-through on how to install and boot GRUB manually into a QEMU disk image. I haven't taken it to the next step with a grub.cfg, but I assume that's pretty straightforward once this main setup is completed.

Suposições:

  • 'grub-install --version' é "grub-install (GRUB) 2.02 ~ beta2-36ubuntu3.2"
  • 'qemu-system-x86_64 --version' é "emulador QEMU versão 2.5.0 (Debian 1: 2.5 + dfsg-5ubuntu10.6), Copyright (c) 2003-2008 Fabrice Bellard"
  • Uma imagem de disco chamada "disk1" no diretório atual
  • / dev / loop0 tem "Tipo de disco: dos" (ou seja, com fdisk)
  • / dev / loop0p1 é uma partição inicializável, já formatada com ext4

Foi assim que inicializei o qemu no 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

Em seguida, o shell do GRUB aparece:

                        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 você tivesse copiado um kernel e um disco RAM para / dev / loop0p1, você poderia inicializá-lo:

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

E aqui está o shell padrão do Linux (porque nenhum / sbin / init estava disponível neste caso)

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

    (initramfs)
    
por 20.12.2016 / 22:53

Tags