1

I am looking for a way to mount an img file (Batocera to be precise) in grub2 and boot from it. It's located in an ntfs formatted partition. I was able to use the loopback command to ls into the image and initiate the boot process only to be greeted with "can't open blockdev" error message. As pointed out in this thread, it's an obvious result given the fact that the image didn't get mounted.

Things I would like to know

Here are some questions which I would like to be answered, preferably with supporting resources for further reading, so that I can understand things better.

  1. Can kpartx, losetup and loop mounting be used to mount the image pre-boot (when in grub2), so that the mounted media can be used as a boot device?
  2. Is it possible to mount the image from grub shell using the built in commands? If so, how?
  3. From similar previous posts, I learnt that an accompanying shell/bash script can be used to mount the image. Where does the script execute? In grub shell?
  4. How do I execute the script? Should the script be run by adding a new grub menu entry or does it need to be added as a kernel parameter?
  5. In the script, how do I specify the path to the image? Should I just use the grub shell format, ie., (hd1, gpt3)/path/to/image.vhd?

Disk information obtained using sudo parted /media/Boot/Batocera.vhd UNIT b print

Number  Start     End       Size     File system  Name                Flags  

1      2048s     3145727s  3143680s  fat32        Basic data partition  msftdata  
2      3145728s  5281791s  2136064s  ext4         Basic data partition  msftdata

Things I've tried

I was able to successfully mount the image from ubuntu desktop using the below methods.

losetup

sudo losetup -Pf /media/Boot/Batocera.vhd

kpartx

$ sudo kpartx -av /media/Boot/Batocera.vhd    
add map loop18p1 (252:2): 0 3082240 linear /dev/loop0 2048    
add map loop18p2 (252:3): 0 17887232 linear /dev/loop0 3084288

Mount and loop

sudo mount /media/Boot/Batocera.vhd /mnt/boot_root \
-o loop,offset=2097152

But when I tried to run the following script during the boot process, nothing seems to happen.

#!/bin/sh

modprobe loop
modprobe vfat
modprobe ext4

mkdir /boot_root
mkdir /SHARE
mount -o loop,offset=1048576B -t vfat /media/Boot/Batocera.vhd /boot_root
mount -o loop,offset=1610612736B -t ext4 /media/Boot/Batocera.vhd /SHARE

GRUB2 Menuentry

menuentry "Batocera" {
    insmod ntfs
    insmod linux
    insmod part_gpt
    insmod part_msdos
    loopback loop (hd1,gpt4)/Boot/Distros/Batocera.vhd
    linux (loop,1)/boot/linux run_script=(hd1,gpt4)/Boot/Scripts/Mount_Partitions_2.sh root=/boot_root label=RECALBOX console=tty3
    initrd (loop,1)/boot/initrd.gz
}

Limitations

If at all possible, I would like to avoid any Kernel modifications / initramfs alterations as it ensures re-usability with future updates.

Threads referred

Booting an EXT4 image file from GRUB2

https://askubuntu.com/questions/69363/mount-single-partition-from-image-of-entire-disk-device

Thanks for the help.

golden_baldy
  • 11
  • 1
  • 2
  • you must run the script from initramfs. use variables. you can make your script more generic with dynamic variables https://stackoverflow.com/a/55559199 – alecxs Aug 23 '20 at 12:23

0 Answers0