The Neutron bootloader reads per-build settings from build.cfg at the project root. A script gen_config.py turns that file into:
internal/config.h— C macros used by the bootloaderbuild.mk— Makefile variables (e.g.KERNEL_FILENAME,EMBED_KERNEL)
You do not edit these generated files by hand; change build.cfg and run make (or python3 gen_config.py) to regenerate them.
build.cfg format
build.cfg is a text file of key-value pairs, one per line. Lines starting with # are comments. Empty lines are ignored. Keys are case-sensitive.
- Strings are written in double quotes, e.g.
kernel_filename = "ATOM.BIN". - Numbers can be decimal or hex (e.g.
0x100000,0x400000). - Booleans are
trueorfalse. - Enums (e.g. log level) use the values listed below.
Supported keys
| Key | Type | Default | Description |
|---|---|---|---|
kernel_filename | string | "ATOM.BIN" | Filename of the packed kernel on the FAT32 root. Use 8.3 uppercase for best compatibility. |
kernel_staging_addr | hex | 0x100000 | Physical address where the kernel file is read into memory. Must be in RAM and not overlap the bootloader. |
kernel_load_addr | hex | 0x200000 | Physical address where the NKRN payload is copied and where the bootloader jumps. Must match the kernel link address. |
kernel_max_size | hex or decimal | 0x400000 (4 MiB) | Maximum payload size in bytes. The bootloader rejects images larger than this. |
log_level | enum | info | quiet, info, or debug. Controls how much is printed over UART (when the C code uses it). |
ansi_colors | bool | true | If true, use ANSI escape codes for colours in serial output; if false, config.h defines empty strings for the colour macros. |
banner_text | string | "Neutron Bootloader v1.0.0" | Line shown in the boot banner (after ” ~ ”). |
bootloader_version | string | "Neutron-1.0" | String written into boot_info_t.bootloader_version (max 15 characters plus NUL). |
kernel_version | string | "v1.0" | Kernel version string to be packed into the NKRN header and written to boot_info_t.kernel_version. Format: “vMAJOR.MINOR” (e.g. “v1.0”, “v2.3”). Max 15 characters plus NUL. |
embed-kernel | bool | false | If true, the packed kernel is embedded into kernel8.img and the bootloader boots without SD/FAT32. If false, the kernel is loaded from the SD card. |
Example build.cfg
The following matches the current build.cfg structure (all keys and embed-kernel option):
# Neutron Bootloader - Build Configuration
# Edit this file to customize bootloader behaviour per build.
# Run 'make' to regenerate internal/config.h from this file.
# Kernel image filename on FAT32 root (8.3 uppercase recommended)
kernel_filename = "CUSTOM.BIN"
# Staging address: where the kernel file is read into memory (must be in RAM)
kernel_staging_addr = 0x100000
# Load/entry address: where payload is copied and where we jump (must match kernel link address)
kernel_load_addr = 0x200000
# Maximum kernel image size in bytes (payload only, after NKRN header)
kernel_max_size = 0x400000
# Log level: quiet | info | debug
log_level = quiet
# Use ANSI colour codes for serial output (true | false)
ansi_colors = true
# Banner line shown at boot (string)
banner_text = "Neutron Bootloader v1.2.0"
# Bootloader version string written into boot_info_t (max 15 chars + NUL)
bootloader_version = "Neutron-1.2.0"
# Kernel version string packed into the NKRN header and written into boot_info_t
# Format: "vMAJOR.MINOR" (e.g. "v1.0", "v2.3")
kernel_version = "v1.0"
# If true, embed the packed kernel into kernel8.img and boot without
# accessing the SD card / FAT32 filesystem. If false, load from SD.
embed-kernel = falseKernel embedding (build.mk)
This is an auto-generated script and must not be changed by hand
- Generated by
gen_config.pyfrombuild.cfg; do not edit by hand. - Included by the main
Makefile(-include build.mk) so Make gets the current config. - Defines several variables:
KERNEL_FILENAME- Name of the packed kernel on the FAT32 root (e.g.ATOM.BIN,CUSTOM.BIN). Used for mcopy when building sd.img.KERNEL_VERSION- Kernel version string (e.g. “v1.0”) frombuild.cfg.KERNEL_VERSION_MAJORandKERNEL_VERSION_MINOR- Parsed integer versions used bypack_kernel.py.EMBED_KERNEL- 1 = embed kernel inkernel8.imgand skip SD; 0 = load from SD and build sd.img by default.
Refreshed when build.cfg changes; make all depends on build.mk so Make re-execs and picks up the new values in the same run.
C macros (internal/config.h)
After generation, the following are available in C (when the bootloader does #include "config.h"):
- Addresses and size:
CFG_KERNEL_FILENAME,CFG_KERNEL_STAGING_ADDR,CFG_KERNEL_LOAD_ADDR,CFG_KERNEL_MAX_SIZE - Logging:
CFG_LOG_LEVEL(0 = quiet, 1 = info, 2 = debug), andCFG_LOG_QUIET,CFG_LOG_INFO,CFG_LOG_DEBUG - Colours:
CFG_ANSI_COLORS(0 or 1). When 1,CFG_ANSI_RESET,CFG_ANSI_BOLD,CFG_ANSI_GREEN,CFG_ANSI_CYAN,CFG_ANSI_YELLOW,CFG_ANSI_REDare the escape sequences; when 0, they are empty strings. - Strings:
CFG_BANNER_TEXT,CFG_BOOTLOADER_VERSION,CFG_KERNEL_VERSION(e.g. “v1.0”) - Kernel version:
CFG_KERNEL_VERSION_MAJORandCFG_KERNEL_VERSION_MINOR(parsed fromkernel_versionin build.cfg, e.g. “v1.0” → major=1, minor=0) - Embed:
CFG_EMBED_KERNEL(0 = load from SD, 1 = use embedded kernel inkernel8.img)
When to regenerate config.h
- Automatically: The Makefile generates
internal/config.handbuild.mkwhen you runmake bootloaderormake allifbuild.cfgis newer than them, or if they are missing. - By hand: Run
python3 gen_config.pyfrom the project root. Usepython3 gen_config.py --verboseto print the output path.
Matching the kernel and SD image
- The kernel filename in
build.cfgmust match the file name you put on the FAT32 partition (e.g. if you setkernel_filename = "MYOS.BIN", copy your packed kernel to the SD root asMYOS.BIN). - The kernel load address in
build.cfgmust match the address your kernel is linked for (e.g. the test kernel uses 0x200000 intest_kernel/linker/kernel.ld). When packing withpack_kernel.py, use--loadand--entryto match (e.g.--load 0x200000 --entry 0x200000). - With
embed-kernel = false, the SD image created bymake sd-imagecopiesK_BIN(defaultbin/atom.bin) to the image using the name fromkernel_filename(e.g.ATOM.BINorCUSTOM.BIN). The Makefile uses the same value formcopy, so changingkernel_filenameinbuild.cfgis enough. - With
embed-kernel = true, no SD image is built by default; the kernel is embedded intokernel8.imgand the bootloader does not access the SD card.