My latest hack is for dual-booters: The OS switcher lets you select the operating system (OS) you wish to boot at the flick of a switch, anytime. Booting the OS of your choice no longer requires you to sit in front of your computer, wait for a boot selection screen to show up, and then press some buttons at just the right time.
Today, when you install Linux and Windows to dual-boot your PC, you typically have to select which OS to load at boot time, often within a certain time window. The longer you set the timeout for the boot selector, the slower it can be to boot your PC (if you’re happy with the defaults). The less time you give yourself, the more fiddly it becomes to switch away from the default. A physical switch would resolve these problems.
Indeed, physical “boot switches” have been built in the past – for example with funky IDE cables and by selectively powering one of two hard drives. However, if you (accidentally) change the switch during operation, that might not be such a good thing…
The OS switcher allows you to select the OS up front, hit the PC’s power button, and walk away, or do whatever you want, until the PC has finished booting into the OS of your choice (or even the boot manager, if you prefer).
The OS switcher is a little, black box has a USB port and a toggle switch. That’s it – simple!
How it works
Inside the plastic project box is an ARM mbed LPC11U24 development board, a piece of stripboard with some female pin headers, the 3-position switch and some wires to connect the switch via the stripboard to pins of the mbed. There’s no need for any passive components, since we can use the mbed’s internal pull-up resistors.
The mbed contains an mbed interface (sometimes referred to as the “mbed magic chip”), which is very interesting. Amongst others, it provides access to a flash disk from both a PC as well as from the ARM Cortex-M0 processor via a technique called Semihosting. Of course, the disk can’t be accessed from both at the same time, but that’s OK. The mbed interface allows me to put a small UEFI boot manager onto the flash disk, together with some config files. Crucially, I can modify these config files from the ARM processor whenever the switch position changes, to update the default boot manager selection. In case the “?” option was selected, I remove the default entry and the timeout all together. That’s how the mbed can influence which OS is booted.
However, there is one more problem to solve: normally the default boot manager resides on a physical disk, rather than on a USB stick, so how can we give the mbed control over the boot process in the first place? One method would involve changing the default boot option in the UEFI firmware settings, and tell the firmware to boot from the mbed “USB stick”. Another method, the one I chose, involves changing the config of my existing boot manager to load the EFI executable (“OS”) found on a disk called “MBED” (this method used to be called chainloading in the days of grub 1 on disks with Master Boot Records (MBRs)).
Loading the mbed’s OS directly from the UEFI firmware would be a little tricky, since:
- The mbed flash cannot be partitioned
- This means we cannot create an EFI system partition
- The flash is formatted as FAT16 chip (IIRC), rather than FAT32, which seems to be used for EFI system partitions.
However, the rEFInd boot manager has no trouble discovering EFI executables on other disks, including the mbed.
One thing to note is that while this IMHO improves usability, it does come with some security risks that should be mitigated. A virus or rootkits infecting the mbed, or changing the configs on-disk, would be bad.
Also, this is a rather roundabout way to let a physical switch decide which OS is loaded. It would’ve been much more straightforward to just add some code to the bootloader to select the OS based on a switch position. But where’s the fun in that? 😉
In this blog post, I’ve described my OS switcher hack. It combines an ARM development board’s USB programmer storage, UEFI knowledge and a bit of hardware to create a physical OS switch.