Jak zainstalować gruba w pliku .img?


26

Zrobiłem następujące:

  1. utworzył pusty plik .img z dd
  2. powiązał go z / dev / loop0 z losetup
  3. utworzył w niej partycję za pomocą fdisk
  4. sformatowano taką partycję za pomocą mke2fs
  5. skopiował niestandardowy system GNU / Linux na tę partycję

Teraz chciałbym, aby plik .img był bootowalny poprzez zainstalowanie gruba w jego katalogu MBR i / boot. Moim celem jest załadowanie pliku .img za pomocą qemu. Byłoby lepiej, gdyby użyto grub2 zamiast starszego typu grub.

Dzięki.


Odpowiedzi:


24

Dotyczy to wersji Grub-pc 1.98 + 20100804-5ubuntu3 (Maverick Meerkat).

Instalator grub2 może zainstalować na sprzężeniu zwrotnym, ale jeśli montujesz za pomocą mapera urządzeń, to się pomyli i uwierzy, że masz schemat LVM, który w tajemniczy sposób kończy się niepowodzeniem z powodu skargi na brak abstrakcji.

Zamiast tego należy samodzielnie skonfigurować urządzenie sprzężenia zwrotnego dla partycji o nazwie, która musi pasować do wzorca „/ dev / loop [0-9]”, tj. Bez oznaczenia partycji na końcu:

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

(Uwaga: jeśli chcesz, aby grub-mkconfig / update-grub działał na tym woluminie, wówczas pętla partycji musi być podłączona do pętli dyskowej w / dev, a nie bezpośrednio do pliku obrazu).

Ponieważ użyłeś fdisk do podzielenia obrazu na partycje, masz tablicę partycji w stylu msdos (aka label) i uruchamiasz się za pomocą BIOS-u. Oprócz umieszczenia stage1 / boot.img w MBR, stage1.5 / core.img zostanie umieszczony w obszarze osadzania w niepartycjonowanej przestrzeni (!), Zaraz po nim, i musi być na to miejsce.

Sztuką jest teraz powiedzieć instalatorowi Grub2 poprzez mapę urządzenia, w jaki sposób twoja konfiguracja sprzężenia zwrotnego będzie mapowana na dyski BIOS na maszynie wirtualnej. (W starszej wersji grub1 zrobiono to bezpośrednio w powłoce). Prawdopodobnie planujesz uruchomić ten obraz jako pierwszy dysk, więc sądzę, że odpowiednie mapowanie to:

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

Tutaj umieściłem mapę urządzenia w obrazie dysku gościa, aby można było wygenerować plik konfiguracyjny rozruchu grub.cfg:

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

(Uwaga: poinstalacyjny pakiet grub-pc uruchomi sondę, która zastąpi mapę urządzenia (!), Więc będziesz musiał napisać ją po instalacji i samemu uruchomić grub-mkconfig / update-grub).

Teraz uruchom instalator z hosta , wskazując na instalację gościa:

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

Na koniec odmontuj wszystko ustawione tutaj przed uruchomieniem qemu na swoim obrazie:

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

Łał! Właśnie natrafiłem na twoją odpowiedź, próbując zrozumieć, dlaczego nie mogłem zaktualizować-gruba zapętlonego, zamrożonego pliku obrazu. Zobaczę, czy to może dotyczyć mojego problemu, ale jest to z pewnością interesujący utwór i bardzo wart mojej uwagi. Dzięki!
filofel,

1
Dobra odpowiedź, niestety chroot /mnt grub-mkconfig -o /boot/grub/grub.cfgnie udaje się, ponieważ grub-mkconfigna dysku .img nie ma żadnych plików binarnych ani nic takiego i /mntjest już zamontowany. Byłoby wspaniale, gdybyś robił to krok po kroku i zapisywał wszystkie szczegóły / polecenia.
Flavius

@RolKau: dziękuję za tę doskonałą dokumentację! Wraz z poniższymi modyfikacjami Toh rozwiązało wiele problemów, jakie miałem przez lata z grub, kiedy osadzano je w środowisku chroot.
sparkie

1
losetup -Pto kolejny dobry sposób montowania pojedynczej partycji: stackoverflow.com/a/15200862/895245
Ciro Santilli 11 改造 中心 法轮功 六四 事件

Dostaję: /usr/sbin/grub-probe: warning: the device.map entry 'hd0,1' is invalid. Ignoring it. Please correct or delete your device.map.więc ta odpowiedź jest bezużyteczna.
Calmarius

11

wielkie dzięki za te wyjaśnienia. Zintegrowałem twoje rozwiązanie z własnymi skryptami z następującymi modyfikacjami (przetłumaczonymi na twoją notację / zmienne):

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

działa to przynajmniej w przypadku ściśnięcia Debiana. Sprawdź poprawność „/boot/grub/grub.cfg”.


1
Czy cat > /mnt/boot/grub/device.mapnależy to zrobić w środowisku chrootowanym? Jeśli tak, ścieżka powinna być /boot/grub/device.map.
cbliard

0

Oto krótkie omówienie, w jaki sposób ręcznie zainstalować i uruchomić GRUB na obraz dysku QEMU. Nie przystąpiłem do następnego kroku z grub.cfg, ale zakładam, że jest to dość proste po zakończeniu głównej konfiguracji.

Założenia:

  • „grub-install --version” to „grub-install (GRUB) 2.02 ~ beta2-36ubuntu3.2”
  • „qemu-system-x86_64 --wersja” to „emulator QEMU w wersji 2.5.0 (Debian 1: 2.5 + dfsg-5ubuntu10.6), Copyright (c) 2003-2008 Fabrice Bellard”
  • Obraz dysku o nazwie „dysk1” w bieżącym katalogu
  • / dev / loop0 ma „Disklabel type: dos” (tj. z fdisk)
  • / dev / loop0p1 jest partycją startową sformatowaną już w ext4

Oto jak uruchomiłem qemu do 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

Następnie pojawia się powłoka 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>

Jeśli skopiowałeś jądro i ram dysku do / dev / loop0p1, możesz go uruchomić:

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

Oto domyślna powłoka systemu Linux (ponieważ w tym przypadku nie było dostępne polecenie / 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)
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.