Làm cách nào để cài đặt grub vào tệp .img?


26

Tôi đã làm như sau:

  1. đã tạo một tệp .img trống với dd
  2. liên kết nó với / dev / loop0 với losetup
  3. đã tạo một phân vùng trong đó với fdisk
  4. định dạng phân vùng như vậy với mke2fs
  5. sao chép một hệ thống GNU / Linux tùy chỉnh vào phân vùng đó

Bây giờ tôi muốn làm cho tệp .img có thể khởi động bằng cách cài đặt grub vào thư mục MBR và / boot của nó. Mục tiêu của tôi là tải tập tin .img bằng qemu. Sẽ tốt hơn nếu grub2 được sử dụng thay vì di sản grub.

Cảm ơn.


Câu trả lời:


24

Đây là phiên bản grub-pc 1.98 + 20100804-5ubfox3 (Maverick Meerkat).

Trình cài đặt grub2 có thể cài đặt cho các thiết bị loopback, nhưng nếu bạn sử dụng trình ánh xạ thiết bị, nó sẽ bị lẫn lộn và tin rằng bạn có sơ đồ LVM, thất bại một cách bí ẩn với một khiếu nại về sự trừu tượng bị thiếu.

Thay vào đó, bạn nên tự thiết lập thiết bị loopback cho phân vùng, với tên phải khớp với mẫu "/ dev / loop [0-9]", tức là không có bất kỳ trình thiết kế phân vùng nào ở cuối:

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

(Lưu ý rằng nếu bạn muốn grub-mkconfig / update-grub hoạt động trên ổ đĩa này, thì vòng lặp phân vùng phải được kết nối với loopback đĩa bên dưới / dev và không trực tiếp với tệp hình ảnh).

Vì bạn đã sử dụng fdisk để phân vùng hình ảnh, bạn có bảng phân vùng kiểu msdos (còn gọi là nhãn) và khởi động bằng BIOS. Ngoài việc đặt giai đoạn1 / boot.img vào MBR, giai đoạn1.5 / core.img sẽ được đặt trong một khu vực nhúng trong không gian không liên kết (!) Ngay sau đó và phải có không gian cho việc này.

Bí quyết bây giờ là nói cho trình cài đặt grub2 thông qua sơ đồ thiết bị về cách thiết lập loopback của bạn sẽ ánh xạ tới các ổ đĩa BIOS trong máy ảo. (Trong di sản grub1, điều này đã được thực hiện trực tiếp trong trình bao). Có lẽ bạn đang dự định khởi động hình ảnh này dưới dạng đĩa đầu tiên, vì vậy tôi đoán ánh xạ thích hợp sẽ là:

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

Ở đây tôi đã đặt bản đồ thiết bị bên trong hình ảnh đĩa khách, để bạn có thể tạo tệp cấu hình khởi động grub.cfg:

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

(Lưu ý rằng trình cài đặt sau của gói grub-pc sẽ chạy một đầu dò ghi đè lên bản đồ thiết bị (!), Vì vậy bạn sẽ phải viết nó sau khi cài đặt và tự chạy grub-mkconfig / update-grub).

Bây giờ hãy chạy trình cài đặt từ máy chủ lưu trữ , trỏ đến cài đặt của khách:

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

Cuối cùng, ngắt kết nối mọi thứ được thiết lập ở đây trước khi bắt đầu qemu trên hình ảnh của bạn:

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

Ồ Tôi vừa chạy vào câu trả lời của bạn trong khi cố gắng hiểu lý do tại sao tôi không thể cập nhật-grub một tập tin hình ảnh được gắn kết, gắn kết. Tôi sẽ xem liệu điều này có thể áp dụng cho vấn đề của tôi không, nhưng đó chắc chắn là một ca khúc thú vị và rất đáng để tôi ủng hộ. Cảm ơn!
filofel

1
Rất tiếc, không may là chroot /mnt grub-mkconfig -o /boot/grub/grub.cfgthất bại vì không có grub-mkconfighoặc có bất kỳ nhị phân nào cho vấn đề đó trong đĩa .img và /mntđã được gắn. Sẽ thật tuyệt nếu bạn thực hiện từng bước và viết tất cả các chi tiết / lệnh.
Flavius

@RolKau: cảm ơn bạn vì tài liệu tuyệt vời này! Cùng với các sửa đổi của toh bên dưới, nó đã giải quyết được nhiều vấn đề tôi gặp phải trong nhiều năm với grub khi nhúng từ trong môi trường chroot.
Sparkie

1
losetup -Plà một cách tốt khác để gắn một phân vùng duy nhất: stackoverflow.com/a/15200862/895245
Ciro Santilli 心 心 事件

Tôi nhận được: /usr/sbin/grub-probe: warning: the device.map entry 'hd0,1' is invalid. Ignoring it. Please correct or delete your device.map.Vì vậy, câu trả lời này là vô ích.
Calmarius

11

cảm ơn rất nhiều vì những lời giải thích này Tôi đã tích hợp giải pháp của bạn vào các tập lệnh của riêng tôi với các sửa đổi sau (được dịch sang ký hiệu / biến của bạn):

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

cái này hoạt động ít nhất là trên bóp debian. Kiểm tra '/boot/grub/grub.cfg' để biết chính xác.


1
Có nên cat > /mnt/boot/grub/device.mapthực hiện trong môi trường chroot? Nếu vậy, con đường nên được /boot/grub/device.map.
chơi cbliard

0

Dưới đây là hướng dẫn nhanh về cách cài đặt và khởi động GRUB thủ công vào hình ảnh đĩa QEMU. Tôi chưa đưa nó đến bước tiếp theo với grub.cfg, nhưng tôi cho rằng điều đó khá đơn giản một khi thiết lập chính này được hoàn thành.

Giả định:

  • 'grub-install --version' là "grub-install (GRUB) 2.02 ~ beta2-36ubfox3.2"
  • 'qemu-system-x86_64 --version' là "trình giả lập QEMU phiên bản 2.5.0 (Debian 1: 2.5 + dfsg-5ubfox10.6), Bản quyền (c) 2003-2008 Fabrice Bellard"
  • Một hình ảnh đĩa có tên "đĩa1" trong thư mục hiện tại
  • / dev / loop0 có "Kiểu đĩa: dos" (nghĩa là với fdisk)
  • / dev / loop0p1 là phân vùng có thể khởi động, đã được tạo thành với ext4

Đây là cách tôi khởi động qemu vào 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

Sau đó, vỏ GRUB xuất hiện:

                        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>

Nếu bạn đã sao chép kernel và đĩa ram vào / dev / loop0p1, bạn có thể khởi động nó:

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

Và đây là shell Linux mặc định (vì không có / sbin / init trong trường hợp này)

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

    (initramfs)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.