Posts: 161
Joined: Sat Oct 14, 2017 9:57 pm


Mon Oct 16, 2017 10:52 pm

Dear fellow Raspberry Pi 3 hobby OS developers

I would like to share a nice little boot loader for the Raspberry Pi 3 with you. It offers an easy way to boot a ramdisk image from a GPT disk. Also sets up 32 bit framebuffer and maps kernel in the higher half of memory. It is Open Source and Free Software, licensed under Public Domain. It targets micro-kernels, and supports ELF64 and PE32+ executable formats. It comes without any warranty in the hope that it will be useful.

I would like to say thanks to rst for helping me out with MMU on AArch64.

EDIT: documentation available in PDF.

How to use

1. First of all, you'll need a higher half linked kernel binary. For an example, see the sample mykernel.aarch64.elf. As the loader focuses on micro-kernels, it should be small, and should be fit in a 2M memory block. You can use the sample's source as a starter for your own kernel.

2. Along with other files, put your micro-kernel binary in an archive file. You can use tar or cpio (hpodc, newc or crc variant) or any other format you like. If you choose a format that the loader does not understand, make sure the first executable in it is your kernel. You can optionally compress your archive with gzip, although not recommended as uncompression is considerably slower than reading from SD card.

3. Get an SDHC card. Create a GPT partitioning scheme with small (~8Mb-16Mb) EFI System Partition on it. Optionally create other partitions for your OS. Format ESP for FAT16, as it's too small for FAT32.

4. Now the tricky part, Raspberry Pi 3 firmware does not understand GPT, so one would have to map ESP in MBR. The easiest way to do that is using the really small mkboot utility provided with the loader.

5. Copy broadcom's bootcode.bin (~50k), start.elf (~3M) and the loader's kernel8.img (~24k) on the SD card.

6. Create a BOOTBOOT directory on the boot partition and copy your archive file as BOOTBOOT\INITRD into.

7. Place the SD card into a Raspberry Pi 3 and plug-in power cord.

8. See your ELF or PE binary booted and running within a blink of an eye! For reference, the sample kernel will show this on screen.


You may want to create a configuration file BOOTBOOT\CONFIG, which holds newline separated "key=value" pairs. C style comments are allowed in it. You can request for a specific screen resolution with "screen=WIDTHxHEIGHT". In lack of this, the native resolution will be used. If you choose tar or cpio as archive, you can specify the name of the executable with "kernel=FILENAME". As mentioned before, without that key the first executable inside the archive is used. All the other keys are unspecified and reserved for your kernel. The configuration file is mapped in memory, and accessible for your kernel as a zero terminated UTF-8 string.

Your kernel will also receive a bootboot struct with all the information (where's the initrd, framebuffer dimension, memory map etc.).


The repository's has a detailed description and a nice troubleshooting section.


The loader's code is a single C source file. On the top, there are different DEBUG defines. Set them and recompile with make. The debug messages will be outputted to the mini-UART (AUX or UART1).

Sample commands

I have my SD card reader at /dev/sdc, change it to your configuration accordingly.

Code: Select all

# fdisk /dev/sdc

Welcome to fdisk (util-linux 2.30.2).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

Device does not contain a recognized partition table.
Created a new DOS disklabel with disk identifier 0xfa00b86e.

Command (m for help): g
Created a new GPT disklabel (GUID: E6B4945A-8308-448B-9ACA-0E656854CF66).

Command (m for help): n p
Partition number (1-128, default 1): 1
First sector (2048-262110, default 2048): 
Last sector, +sectors or +size{K,M,G,T,P} (2048-262110, default 262110): +8M

Created a new partition 1 of type 'Linux filesystem' and of size 8 MiB.

Command (m for help): t 1
Selected partition 1
Partition type (type L to list all types): 1
Changed type of partition 'Linux filesystem' to 'EFI System'.

Command (m for help): w
The partition table has been altered.
Syncing disks.
# mkfs.vfat -F 16 -n "EFI System" /dev/sdc1
mkfs.fat 4.1 (2017-01-24)
mkfs.fat: warning - lowercase labels might not work properly with DOS or Windows
# mkboot /dev/sdc
mkboot: GPT ESP mapped to MBR successfully

Posts: 161
Joined: Sat Oct 14, 2017 9:57 pm


Tue Nov 14, 2017 5:13 pm

Dear All,

Because I had questions about Public Domain, I've re-licensed the loader under the MIT licence. Hopefully I've changed the copyright notice everywhere :-)

I've also added support for raspbootin, so that you can load the initial ramdisk image over serial from a computer running the raspbootcom utility. I've provided a slightly modified version, which is easier to compile on Linux, and which handles the payload file as optional.


Return to “Bare metal, Assembly language”

Who is online

Users browsing this forum: No registered users and 4 guests