Chapter 1: Introduction

I’ve wanted to write an general purpose operating system for a long time - it’s one of my computing bucketlist items. kOS, pronounced “chaos”, is my project to do that. Along the way, I’m going to write up my work [1] to help me understand what’s going on.

kOS will be a 64-bit operating system.

The first target

The first target is the Raspberry Pi 4B; mine has 8GB of memory available. It has a Broadcom BCM2711 System on Chip (SoC), which features a Cortex A72 quad-core ARMv8 processor running at 1.5 GHz. The L1 cache is 32kB for data, 48kB for instructions, and the L2 cache is 1MB. It also has a Videocore VI GPU, which has built-in support for OpenGL ES 3.1 and Vulkan 1.2.

As for I/O, it has a PCIe bus, a DSI [2] and CSI [3] bus [4], support for up to six I2C buses, up to six UARTs [5], and up to five SPI buses [6]. There are also a pair of HDMI outputs.

The BCM2711 has 58 general purpose I/O lines; 27 of these are exposed via the 40-pin header on the Raspberry Pi.

Some of the relevant pinouts:

_images/pinout.png

40-pin header pinout diagram, courtesy of pinout.xyz.

Booting the target

The Raspberry Pi documentation describes the boot sequence; there is an SPI flash EEPROM that has the initial bootloader.

  1. The SoC powers up.

  2. If the nRPIBOOT GPIO is high, or if the OTP hasn’t configured an nRPIBOOT pin [7], try to load recovery.bin [8] and update the SPI EEPROM.

  3. Try to load the second-stage bootloader from the SPI EEPROM.

  4. Initialize SDRAM and clocks.

  5. Read the EEPROM configuration files ().

  6. Check to see if a HALT is requested.

  7. Read the next boot mode from the BOOT_ORDER parameter in the EEPROM configuration. The boot modes are:

    • RESTART: jump back to the first boot mode in the parameter.

    • STOP: display the start.elf error pattern (see the appendices for a description of these) and loop indefinitely.

    • SD_CARD: try to load from the SD card.

    • NETWORK: use DHCP to get an IP address, then use either DHCP or TFTP to get a boot image.

    • USB-MSD: check for USB mass storage, and try to load firmware from each LUN discovered.

    • NVME: the same, but using NVMe.

    • RPIBOOT: trying to load firmware from a USB device connected to the USB-OTG port.

The first partition on the SD card must be a FAT partition, from which the bootloader looks for certain files:

  • Prior to the Pi 4, bootcode.bin is loaded first, which then loads a start.elf variant. The Pi 4 uses its SPI EEPROM instead.

  • The start.elf variants are firmware. The start4 versions are used for the Raspberry Pi. - start.elf: basic firmware. - start_x.elf: has additional codecs. - start_db.elf: used for debugging. - start_cd.elf: cut-down firmware, removing hardware blocks.

  • The start.elf firmware is paired with an appropriately-named linker file, fixup.dat.

  • config.txt: RPi configuration.

  • overlays/: device-tree overlays

The minimum we’ll need to bring up the kernel are

  • bcm2711-rpi-4-b.dtb

  • config.txt

  • fixup4.dat

  • start4.elf

Finally, our kernel8.img will go in the partition.

Resources

Footnotes