On Linux and macOS you can build and run Neutron using neutron.sh. The script is the same as the Windows neutron.ps1 script: it runs Make inside a Docker container (Ubuntu 24.04, AArch64 toolchain, parted, mtools, dosfstools) and can run QEMU on the host or inside the container. You do not need a native cross-compiler or SD tools on the host.

Prerequisites: Docker (e.g. Docker Engine on Linux, Docker Desktop on macOS), QEMU for Linux/MacOS (For running bootloader on host machine instead of docker) and a shell (bash).

Do not run the script from a directory other than the Neutron project root. The script binds the current directory as /Neutron in the container; if you run it from elsewhere, the wrong folder will be used and artefacts may not appear where you expect.

Usage: ./neutron.sh <command> [options]. The Docker image is built automatically when needed (e.g. on first build or run).

Quick Start

The Docker container has QEMU installed and can be used for testing the bootloader:

./neutron.sh build   # detect latest version and compile the bootloader
./neutron.sh emu     # run the compiled bootloader inside the Docker container QEMU

Build

The default target is all:

./neutron.sh build              # same as: make all
./neutron.sh build all          # bootloader + kernel (+ sd.img unless embed-kernel=true)
./neutron.sh build bootloader   # only kernel8.img
./neutron.sh build kernel       # build packed test kernel (outputs bin/atom.bin)
./neutron.sh build sd-image     # only sd.img
./neutron.sh build debug        # build the debug artefacts of the binaries
./neutron.sh build clean        # remove build and debug artefacts
./neutron.sh build clean-debug  # remove only debug artefacts
./neutron.sh build size         # section sizes

Using a prebuilt kernel

Pass --kernel <path> to skip the test kernel build and use your own packed NKRN image:

# Prebuilt packed NKRN image (already has the NKRN header)
./neutron.sh build all --kernel /path/to/prebuilt.bin
 
# Raw binary (no NKRN header yet) — add --pack to run pack_kernel.py first
./neutron.sh build all --kernel /path/to/raw.bin --pack

The script copies the file to bin/custom_kernel.bin (accessible inside the container via the existing bind-mount) and passes K_BIN=bin/custom_kernel.bin to Make automatically. Both sd-image and the embedded-kernel path pick it up from there.

Run QEMU on host

Requires qemu-system-aarch64 on PATH. Builds artefacts if missing; use --build to force rebuild:

./neutron.sh run        # run the compiled bootloader in host machine QEMU
./neutron.sh run --build   # force build the bootloader and run in host machine QEMU

Run QEMU inside Docker

No host QEMU needed. Builds artefacts if missing; use --build to force rebuild:

./neutron.sh emu        # run the compiled bootloader in Docker container QEMU
./neutron.sh emu --build   # force build the bootloader and run in Docker container QEMU

Interactive shell

Open a bash shell in the build container:

./neutron.sh shell   # access the Docker container root shell

Docker image and custom commands

./neutron.sh docker build         # build image only
./neutron.sh docker tag          # tag image as latest
./neutron.sh docker bash         # same as shell
./neutron.sh docker "make clean" # run arbitrary command in container

Help

./neutron.sh help

Summary of neutron.sh commands

CommandDescription
./neutron.sh build [target] [—kernel path] [—pack]Build in Docker (default target: all). Stages external kernel if --kernel is given; packs it first if --pack is also given.
./neutron.sh run [—build]Run QEMU on host; build first if artefacts missing.
./neutron.sh emu [—build]Run QEMU inside Docker; build first if artefacts missing.
./neutron.sh shellOpen interactive bash in container.
./neutron.sh docker build, tag, bash, or commandImage build/tag, shell, or run a command in container.
./neutron.sh helpShow usage and all commands.

For Make targets and variables, see Make Targets.