This page lists the main source components of the bootloader and their roles. Paths are relative to the Neutron project root.

Assembly

boot/start.S

  • First code executed after load at 0x80000.
  • Receives DTB address from ARM firmware in x0; preserves it in x19 (callee-saved).
  • Parks secondary cores; detects EL; drops from EL2 to EL1; disables MMU/caches; sets stack to 0x80000; zeroes BSS; calls neutron_main(dtb_addr) with DTB address as parameter.
  • Defines a minimal exception vector table (all slots branch to an unhandled-exception stub).
  • Must be assembled with access to internal/aarch64.h for SPSR and related constants.

Bootloader Core (C)

neutron/main.c

  • Entry point neutron_main(uintptr_t dtb_addr) called from start.S, receives DTB address from ARM firmware.
  • Initialises UART, prints colourized banner with bootloader identification, prints CPU exception level and MPIDR.
  • Queries mailbox for board_revision and arm_mem_size; identifies board type (RPi Zero 2W, generic RPi, or QEMU simulation).
  • Kernel source selection (based on CFG_EMBED_KERNEL from build.cfg):
    • SD/FAT32 path (CFG_EMBED_KERNEL = 0): initialises SD card, mounts FAT32, reads the file named by CFG_KERNEL_FILENAME (default: kernel.bin) into staging buffer at CFG_KERNEL_STAGING_ADDR (0x100000).
    • Embedded path (CFG_EMBED_KERNEL = 1): obtains packed kernel from _binary_build_kernel_embed_bin_start.
  • Checks NKRN magic signature, calls bl_load_kernel() to validate header and CRC32, copy payload to configured load address, and fill boot_info_t.
  • Performs 3-second boot countdown.
  • Calls bl_boot_kernel(entry_addr, boot_info, dtb_addr) with kernel entry address, boot info pointer, and DTB address.
  • On any fatal error (SD init, FAT32 mount, file not found, bad magic, load failure), prints a colourized error message and halts in a WFE loop.

neutron/bootloader.c

  • bl_load_kernel(uintptr_t src, boot_info_t *out_info): Validates the NKRN header at src (magic, version, sizes), verifies payload CRC32 checksum (IEEE 802.3 polynomial), displays kernel metadata (name, version, load/entry addresses, size), copies payload to header.load_addr, fills boot_info_t at BOOT_INFO_ADDR (0x1000) with kernel info and bootloader version. Returns BL_OK or an error code.
  • bl_boot_kernel(uintptr_t entry_addr, boot_info_t *info, uintptr_t dtb_addr): Executes DSB/ISB for memory visibility, then branches to kernel at entry_addr using custom calling convention: x0 = pointer to boot_info_t, x1 = DTB address. Does not return.
  • Provides crc32() function (IEEE 802.3 polynomial) and internal helpers bl_memcpy, bl_memset, bl_uint_to_str, and memory utilities (no libc).

Drivers

driver/uart.c

  • PL011 UART at UART0_BASE (0x3F201000). Configures GPIO 14/15 as ALT0, sets baud (115200, 48 MHz clock), 8N1, FIFO enabled. Provides uart_init, uart_putc, uart_puts, uart_getc, uart_printf, and hex/decimal output helpers.

driver/gpio.c

  • BCM2837 GPIO at GPIO_BASE. Implements gpio_set_func, gpio_set_pull, gpio_set, gpio_clear, gpio_get. Used by the UART driver to mux the UART pins.

driver/mbox.c

  • VideoCore mailbox at MBOX_BASE. Implements mbox_call() and wrappers mbox_get_board_revision() and mbox_get_arm_mem_size(). Uses a 16-byte-aligned buffer for property tags.

driver/sdcard.c

  • SD/MMC card initialisation and block read. Uses the EMMC/SDHCI controller (see internal/sdcard.h for register layout). Provides sdcard_init(), sdcard_read_block(), sdcard_read_blocks().

driver/fat32.c

  • Read-only FAT32. Reads MBR, finds first partition, parses BPB, walks FAT and directory to find a file by name. Provides fat32_mount() and fat32_read_file(). Used to read the packed kernel file (name from CFG_KERNEL_FILENAME) from the SD card.
    • Used only when CFG_EMBED_KERNEL = 0.

Linker Script

linker/bootloader.ld

  • ENTRY(_start). Load address 0x80000. Sections: .text.boot, .vectors (0x800-aligned), .text, .rodata, .data, .bss. Exports __bss_start, __bss_end, and _stack_top (0x80000).

Headers

  • include/neutron.h: Shared ABI (boot_info_t, magic, BOOT_INFO_ADDR) and common MMIO defs used by both bootloader and test kernel.
  • internal/platform.h: Additional platform definitions (SDHOST/Mailbox bases, mailbox tags).
  • internal/bootloader.h: NKRN header layout and bootloader API (bl_load_kernel, bl_boot_kernel, error codes).
  • internal/uart.h, internal/gpio.h, internal/mbox.h, internal/sdcard.h, internal/fat32.h: Driver APIs.
  • internal/aarch64.h: SPSR and related constants for EL2 to EL1.

Build Output

  • Object files go under build/ (e.g. build/boot/start.o, build/neutron/main.o).
  • The linker produces build/neutron.elf; objcopy -O binary produces bin/kernel8.img.

For driver details and register usage, see Drivers.