Controlling Default GRUB Boot Option via USB
On my main desktop PC I primarily use Linux (Currently Fedora 38) but I do dual-boot with Windows for testing or for some games that don’t work quite right in Linux. One thing I’ve always wanted is some level of external physical control over which OS will be used on start-up. If I’m doing something that requires restarts, it’s annoying to be vigilant during boot to choose the right OS, and sometimes I like to switch on my PC then do something else like make a cup of tea (even though boot only takes like 10 seconds).
In searching, I came across this hackaday article which uses a proper hardware switch along with a microcontroller board. I didn’t have a good switch on-hand, but looking at the grub code of the mentioned project led me to a simpler option. The code used the GRUB search command which can essentially allow you to conditionally check if a filesystem exists.
Using this I put together a simplistic solution that changes the default GRUB entry depending if you have a specific USB storage drive inserted during boot:
search --no-floppy --fs-uuid --set usbswitch B2B0-DC58 if [ "$usbswitch" ] ; then set default=4 fi
That’s the GRUB2 config code. There’s a couple of bits to configure for your own use-case:
- Change the
B2B0-DC58ID to be a filesystem UUID on your own USB storage drive.
- You can get filesystem info, with UUID shown, via:
- Change the
set default=4to be the boot option you want to be default when the USB is plugged in.
- They are usually shown in order in the grub menu, with 0 being the top option.
Usage in Fedora
This is how I added the above config on my Fedora 38 system which is using EFI boot:
I created a
/etc/grub.d/50_usb_selector file with the below contents:
#!/usr/bin/sh # # Changes default boot option if specific USB filesystem is plugged in. # Change the ID at the end of the search command below to be the # UUID of the filesystem on the USB. # Change the 4 at the end of the set command to change the boot entry # that should be made default when the USB is plugged in. cat <<'EOF' search --no-floppy --fs-uuid --set usbswitch B2B0-DC58 if [ "$usbswitch" ] ; then set default=4 fi EOF
Then I rebuilt the grub config via:
grub2-mkconfig -o /boot/grub2/grub.cfg (following guidance from the Fedora docs).
Building on the idea
I think it should be simple to evolve this into a hardware switch, without getting a custom microcontroller board involved. We could just do what’s done here but on a switchable USB extension (with data support).
While properly exploring grub for the first time, I noticed it also has some networking commands, including one to perform a DNS lookup. This got me wondering if I could control the boot option via providing a specific DNS response from elsewhere on my network, so I could maybe configure the current boot option via software remotely, like via Home Assistant for example. Would need to dig into use of this command and the specific of DNS to validate this though.