This page documents the main Make targets and variables used to build Neutron. The Makefile is in the project root.

Default Target

Invoking make with no arguments runs the default target all, which depends on bootloader, kernel, and sd-image. Thus a full build produces:

  • bin/kernel8.img (bootloader binary)
  • bin/atom.bin (packed test kernel)
  • bin/sd.img (64 MiB FAT32 image with ATOM.BIN in the root)

Phony Targets

all
Builds bootloader, kernel, and SD image. Prints a short summary and mentions make qemu-rpi.

bootloader
Builds only the bootloader. Produces build/neutron.elf and bin/kernel8.img. Dependencies: boot assembly and C sources, linker script.

kernel
Builds only the test kernel and packs it. Produces build/kernel_raw.elf, build/kernel_raw.bin, and bin/atom.bin. The pack step is done by pack_kernel.py with default load/entry 0x200000.

sd-image
Creates the SD image from the existing bin/atom.bin. Requires parted, mtools, and (for the current recipe) a working mformat and mcopy. Produces bin/sd.img (64 MiB, MBR, one FAT32 partition from 1 MiB to end, volume label NEUTRON, file ATOM.BIN in root).

clean
Removes all files under build/ and bin/. Use this before a fresh build or to free space.

qemu-rpi
Depends on all. Invokes QEMU with:

  • -machine raspi3b -cpu cortex-a53 -m 1G
  • -kernel bin/kernel8.img
  • -drive file=bin/sd.img,if=sd,format=raw
  • -serial mon:stdio -display none

size
Prints section sizes for build/neutron.elf and build/kernel_raw.elf. Useful to check code and data size.

help
Prints a short help message listing the main targets and the CROSS variable.

Variables

CROSS
Toolchain prefix. Default: aarch64-linux-gnu-. Must include the trailing hyphen. Example: make CROSS=aarch64-none-elf- all.

CC, AS, LD, OBJCOPY, OBJDUMP, SIZE
Derived from CROSS (e.g. $(CROSS)gcc, $(CROSS)ld). The assembler is invoked via the C compiler ($(CROSS)gcc) for preprocessing of .S files.

BUILD_DIR, BIN_DIR
Directories for object files and final binaries. Defaults: build, bin.

QEMU, QEMU_MACHINE, QEMU_CPU, QEMU_MEM
Used to form the QEMU command. Values: qemu-system-aarch64, raspi3b, cortex-a53, 1G.

SD_SIZE_MB
Size of the SD image in MiB. Default: 64.

Output Files

FileTargetDescription
build/neutron.elfbootloaderLinked bootloader ELF
bin/kernel8.imgbootloaderBootloader binary (objcopy from neutron.elf)
build/kernel_raw.elfkernelLinked test kernel ELF
build/kernel_raw.binkernelTest kernel raw binary
bin/atom.binkernelPacked kernel (NKRN header + kernel_raw.bin)
bin/sd.imgsd-imageFAT32 disk image with ATOM.BIN

Compiler and Linker Flags

  • ARCH_FLAGS: -march=armv8-a -mtune=cortex-a53 -mgeneral-regs-only -mlittle-endian
  • CFLAGS: ARCH_FLAGS plus -ffreestanding -fno-builtin -fno-stack-protector -fno-pie -fno-pic -nostdlib -nostdinc -std=gnu11 -Wall -Wextra -Werror -O2 -g and include paths.
  • ASFLAGS: ARCH_FLAGS plus -ffreestanding -nostdlib and include path, with -D__ASSEMBLER__.
  • BL_LDFLAGS: -nostdlib -T linker/bootloader.ld -Map=build/neutron.map --no-dynamic-linker --no-warn-rwx-segments
  • K_LDFLAGS: -nostdlib -T test_kernel/linker/kernel.ld -Map=build/kernel.map --no-dynamic-linker

The bootloader is linked with ld directly; the kernel is linked with ld as well. No startup files or C library are linked. The kernel pack step is separate (Python script) and must be run for the bootloader to load the kernel; the Makefile runs it as part of the kernel target.

For building on Linux/macOS see Linux and macOS; for Windows with Docker see Windows.