The purpose of this article is to explain how to install GRUB on an USB stick, or any other kind of USB mass-storage device, to make it bootable in either legacy BIOS or UEFI mode and allow to load live images installed in a directory.
It is a complement to this article about using GRUB to boot a live image written as a file rather than an image.
After this, the device has a little wasted space and a directory named boot, but is otherwise completely usable for other tasks.
This is written as a script, to have it compute the partitions positions and sizes automatically based on the size of the USB stick. The size can be obtained from /proc/partitions
(un units of 1024, so need to multiply by 2) or using /sbin/blockdev --getsz
.
We assume we have read and write permissions on the device and use pmount
to mount partitions, but otherwise we do not need root privileges. Note that sfdisk
is probably not in the default path.
Device path: | |
Device size: | × 512 |
EFI partition min size: | × 1024² |
EFI partition alignment: | × 1024² |
Partitions label: | |
Filesystem label: | (max 11, usually uppercase) |
First, let us wipe the device, so that traces of previous partitions and attemps do not interfer. Just wipe the areas outside the main partitions.
dd bs=512 if=/dev/zero seek=0 count=2048 of=/dev/sdc dd bs=512 if=/dev/zero seek=15767552 count=2048 of=/dev/sdc
Create the partitions. We need a GPT scheme with a big data partition, a small EFI system partition (~100 megaoctets usually recommended, less than on required for GRUB) and a tiny BIOS boot partition (necessary to install MBR GRUB). We also need a protective/hybrid MBR for system that do not understand GPT, with the data and EFI partition and one covering the GPT. The --no-reread
is needed if root privileges are not used, due to a tiny bug in sfdisk
.
sfdisk --no-reread /dev/sdc <<EOF label: gpt unit: sectors sector-size: 512 1 : start=2048, size=15699968, type=EBD0A0A2-B9E5-4433-87C0-68B6B72699C7, name="multiboot" 2 : start=15702016, size=65536, type=uefi, name="multiboot_EFI" 3 : start=15767552, size=2015, type=21686148-6449-6E6F-744E-656564454649, name="multiboot_BIOS" EOF sfdisk --no-reread -Y dos /dev/sdc <<EOF label: dos sector-size: 512 1 : start=2048, size=15699968, type=0c, bootable 2 : start=15702016, size=65536, type=ef 3 : start=1, size=2047, type=ee EOF
Create the filesystems.
mkdosfs -n MULTIBOOT /dev/sdc1 mkdosfs /dev/sdc2
Mount the partitions and install GRUB, three times (EFI 64, EFI 32 and legacy).
pmount /dev/sdc1 /media/boot mkdir /media/boot/boot pmount /dev/sdc2 /media/efi grub-install --target=x86_64-efi --removable --no-nvram \ --root-directory=/media/boot \ --boot-directory=/media/boot/boot \ --efi-directory=/media/efi grub-install --target=i386-efi --removable --no-nvram \ --root-directory=/media/boot \ --boot-directory=/media/boot/boot \ --efi-directory=/media/efi grub-install --target=i386-pc \ --root-directory=/media/boot \ --boot-directory=/media/boot/boot \ /dev/sdc pumount /media/efi
Initial configuration for GRUB. The background image can be found in the Debian package desktop-base
.
cp /usr/share/desktop-base/active-theme/grub/grub-16x9.png /media/boot/boot/grub/ cat > /media/boot/boot/grub/grub.cfg <<EOF insmod efi_gop insmod font insmod gfxterm insmod png loadfont /boot/grub/fonts/unicode.pf2 set gfxmode=auto set gfxpayload=keep terminal_output gfxterm if background_image /boot/grub/grub-16x9.png ; then set color_normal=white/black set color_highlight=black/white else set menu_color_normal=cyan/blue set menu_color_highlight=white/blue fi EOF
Let us put something in the device and unmount it.
cp /path/to/some.iso /media/boot/boot/ vim /boot/grub.cfg pumount /media/boot
ISO images can then be copied to the key and stances added to boot/grub/grub.cfg
like explained in this article.
Extra: to test the disk without rebooting a machine, we can use qemu, with the packages qemu-system-x86
, qemu-system-gui
and ovmf
for the UEFI firmware. Assuming the device is plugged as /dev/sdc
and we have a raw disk image /tmp/disk
we want to use, it can look like that:
cp /usr/share/qemu/OVMF.fd /tmp/ qemu-system-x86_64 \ -enable-kvm \ -drive if=pflash,format=raw,file=/tmp/OVMF.fd \ -drive file=/dev/sdc,format=raw,index=0,media=disk \ -drive file=/tmp/disk,format=raw,index=1,media=disk \ -boot order=c \ -m 512 \ -display gtk
It is possible that 500 Mo be insufficient for some distros. Even with much more I wasn't able to let Debian Live finish booting.
Extra: configuring Debian Live directly and attempting to enable persistence.