If you squint really hard – a partition table is basically a filesystem with only a handful of files – a partition table of, say, 4 partitions, is conceptually pretty much the same as a filesystem with only 4 files in it – the filesystem labels are the filenames, and the partitions are just the files.
So why don’t we use a filesystem as a partition table and boot a OS from it? The pros of doing that is quite obvious: All partitioning operations previously done using
parted can now be done with file managers, or common UNIX utilities like
truncate. To add a new partition, add a new file; to remove a partition, delete the file; to make a partition larger, simply extend the file – no more moving other partition around like playing Klotski.
This is especially true for beginners – one big hurdle to jump using a Raspberry Pi – is to prepare a SD card. Without prior knowledge of MBR or GPT, this process is quite error prone. If we’re using a filesystem as a partition table, the provisioning process is just copying some files into a FAT32 disk, which comes standard on most SD cards. Upgrading the OS is no different from copying files – which can be easily done in any OS.
Let’s get a proof of concept running – we want to prepare a SD card with a single partition, have a image file
root.img in there, and boot off of it. In linux terms – mount the
root.img as a loop device, and use that as root.
Linux itself, does not have the capability of directly booting from a image file as root. We have to do it in a more roundabout way.
- Boot to a initramfs
- Mount the filesystem containing the image file, in the case of Raspberry Pis, this is
- Mount the image file using a loop device.
switch_rootto the actual rootfs.
For the initramfs, we use BusyBox with a custom init file, with a few extra utilities written in shell script.
The boot process is roughly the following:
- Linux starts
/initin the initramfs.
- Wait 5 seconds, if the user interrupts, offer options to use a rescue shell, reboot or shutdown.
/bootand give control to
/boot/init. We do this because initramfs is not persistent, and we want to boot process to be configurable.
- Wait 5 seconds, if the user interrupts, let the user select a image to boot.
- Mount the image (default
- Raspbian takes over.