The Neutron bootloader loads a packed kernel image: a 64-byte NKRN header followed by the raw AArch64 payload. This page describes how to produce that image with the provided script and how to put it on the SD card for the bootloader to find.

pack_kernel.py

The project includes a Python 3 script, pack_kernel.py, in the project root. It reads a raw kernel binary, computes the CRC32 of the payload, and writes a file that starts with the NKRN header and then the payload. The bootloader expects that file to be named ATOM.BIN in the root of the first FAT32 partition on the SD card.

Usage

python3 pack_kernel.py <raw_binary> [options]

Positional argument: Path to the raw kernel binary (e.g. the output of objcopy -O binary kernel.elf kernel.bin).

Options:

OptionDefaultDescription
-o, --outputkernel.binOutput file path.
-n, --nameNeutron KernelName string in the header (up to 39 bytes).
--load0x200000Load address (hex): where the bootloader will copy the payload.
--entry0x200000Entry address (hex): where the bootloader will jump.
--version-major1Major version number (stored as major << 16 in header).
--version-minor0Minor version number.
--verify(flag)Verify an existing packed image instead of packing.

Examples

Pack the default test kernel output with default load/entry:

python3 pack_kernel.py build/kernel_raw.bin -o bin/atom.bin -n "Neutron Test Kernel"

Pack with custom name and version:

python3 pack_kernel.py mykernel.bin -o myimg.bin -n "MyOS 0.1" --version-major 0 --version-minor 1

Verify an existing packed file:

python3 pack_kernel.py bin/atom.bin --verify

CRC32

The script uses Python’s zlib.crc32 with the same convention as the bootloader (IEEE 802.3 polynomial, result masked to 32 bits). The header stores the CRC of the payload only (bytes after the 64-byte header). The bootloader recomputes this and refuses to boot if it does not match.

The Makefile runs pack_kernel.py automatically when you build the kernel target. It passes the output of the kernel build (build/kernel_raw.bin) and writes bin/atom.bin with a fixed name string. You can run the script by hand for custom kernels.

SD Card Layout

The bootloader:

  1. Initialises the SD card.
  2. Mounts the first partition as FAT32 (via MBR).
  3. Looks for the file ATOM.BIN in the root directory (8.3 name, case-insensitive).

So the packed image must appear on the SD card as a file named ATOM.BIN in the root of the first partition. The Makefile’s sd-image target creates a 64 MiB disk image, creates one FAT32 partition from 1 MiB to the end, and copies bin/atom.bin into the root as ATOM.BIN using mcopy. That image is used by QEMU as the SD card (-drive file=bin/sd.img,if=sd,format=raw).

Deploying to Real Hardware

For a real Raspberry Pi:

  1. Prepare an SD card with the official boot files (e.g. bootcode.bin, start.elf, fixup.dat) and your kernel8.img (the Neutron bootloader).
  2. Ensure the first partition is FAT32 and contains ATOM.BIN in the root. You can copy the contents of the first partition of bin/sd.img onto the card, or format the partition as FAT32 and copy bin/atom.bin (or your packed image) onto it as ATOM.BIN.
  3. Boot the board. The GPU loads kernel8.img at 0x80000; Neutron runs, mounts the FAT partition, reads ATOM.BIN into 0x100000, validates the NKRN header, copies the payload to the load address, and jumps to the kernel.

If you use a different filename (e.g. MYOS.BIN), you must change the bootloader source ( neutron/main.c) to call fat32_read_file("MYOS.BIN", ...) and rebuild the bootloader. The default is ATOM.BIN.

Summary

  1. Build your kernel to a raw binary (link at load address, e.g. 0x200000; objcopy -O binary).
  2. Run pack_kernel.py raw_binary.bin -o atom.bin -n "Your Name" (and adjust —load/—entry if not 0x200000).
  3. Place the output as ATOM.BIN in the root of the first FAT32 partition on the SD card (or in the SD image used by QEMU).
  4. Boot with Neutron as kernel8.img; it will load and run your kernel.

For the header format and validation rules, see NKRN Image Format. For building the kernel binary, see Building a Kernel.