kei Building & Deploying

Overview

kei produces kei-kernel.bin — the ARM64-enabled Asterinas kernel consumed by aris. This guide covers building the kernel, testing in QEMU, and deploying to physical hardware.

Build Pipeline

flowchart LR
    SRC["Source\nostd/ kernel/ bsp/"] -->|"cargo build\n(aarch64)"| BIN["kei-kernel.bin"]
    BIN --> QEMU["QEMU Test\n(virt/cortex-a55)"]
    QEMU -->|passes| PACK["Package\n(DTB + initramfs)"]
    PACK --> ARIS["aris firmware\n(image.img)"]
    ARIS --> FLASH["Flash SD card"]
    FLASH --> BOARD["NanoPi R3S"]

Prerequisites

Quick Build

# One-time setup
just setup        # Configure git remotes and Rust targets

# Sync upstream sources
just vendor       # Absorb latest upstream asterinas (squash)
just pull-arm64   # Pull ARM64 code from wanywhn fork (one-time)
just versions     # Show upstream baseline versions

# Build for the NanoPi R3S
just build        # Builds kei-kernel.bin for aarch64/armv8

# Run QEMU boot tests
just test-all     # Boot-tests all supported architectures

Cross-Compilation

For cross-compiling from x86_64 to aarch64:

# Add the ARM64 target (one-time)
rustup target add aarch64-unknown-none-softfloat

# Install GCC cross-toolchain (distribution-dependent)
# Ubuntu / Debian:
sudo apt install gcc-aarch64-linux-gnu binutils-aarch64-linux-gnu

# Build
cargo build --release --target aarch64-unknown-none-softfloat \
  -p kei-kernel

The kernel binary is a raw ARM64 Image (Linux boot protocol), not an ELF. It boots directly from U-Boot via the booti command.

QEMU Testing

Test the kernel in QEMU before deploying to hardware:

flowchart TB
    subgraph Host["Host Machine"]
        KERN["kei-kernel.bin"]
        DTB["nanopi-r3s.dtb"]
        QEMU["QEMU\n(virt, cortex-a55)"]
    end
    KERN --> QEMU
    DTB --> QEMU
    QEMU -->|"serial output\n(logged)"| LOG["Console log"]
    QEMU -->|"exit 0 = pass"| RESULT["Test result"]

Test Matrix

QEMU MachineCPURAMStatusCommand
virtcortex-a552GB✅ Primaryjust test
virtcortex-a722GB🔲 Planned
virtmax4GB🔲 Planned
sbsa-refmax4GB🔲 Planned
# Run the primary test target
just test

# Manual QEMU invocation
qemu-system-aarch64 \
  -machine virt,gic-version=3 \
  -cpu cortex-a55 \
  -m 2G \
  -kernel output/kei-kernel.bin \
  -nographic

Physical Deployment

NanoPi R3S

Deploying kei to a physical NanoPi R3S:

flowchart TB
    subgraph Build["Build Host"]
        KERN["kei-kernel.bin"]
        DTB["nanopi-r3s.dtb"]
        INIT["initramfs.cpio.gz"]
    end
    subgraph Deploy["Deploy"]
        IMG["image.img"]
        SD["SD Card"]
        BOARD["NanoPi R3S"]
    end
    KERN --> IMG
    DTB --> IMG
    INIT --> IMG
    IMG -->|"dd / just flash-sd"| SD
    SD --> BOARD

Flash to SD Card

# Build the complete firmware image (includes kei-kernel.bin)
# Run from aris repository — aris packages kei as a submodule/dependency
just build-board nanopi-r3s

# Flash to SD card
sudo dd if=output/nanopi-r3s/image.img of=/dev/sdX bs=4M status=progress
sync

Boot Verification

After inserting the SD card and powering on, connect via USB-TTL serial (1500000 baud, 8N1):

U-Boot 2024.01 (Jan 01 2024 - 00:00:00 +0000)
...
## Loading kernel from mmc 0:1
   Image Name:   kei-kernel
   Image Type:   AArch64 Linux Kernel Image
   Data Size:    4194304 Bytes = 4 MiB
   Load Address: 00000000
   Entry Point:  00000000
## Flattened Device Tree blob at 44000000
   Booting using the fdt blob at 0x44000000

kei-kernel booting...
[KEI] initialising GICv3...
[KEI] initialising ARM Generic Timer...
[KEI] starting SMP...
[KEI] 4 cores online
...
aris-core v0.1.0 starting...
evernight daemon starting...

Boot Order

flowchart TB
    ROM["Mask ROM"] --> SPL["U-Boot SPL"]
    SPL --> TPL["U-Boot Proper"]
    TPL -->|"load kernel + DTB\nfrom mmc"| KEI["kei-kernel.bin"]
    KEI -->|"Transfer to EL1"| INIT["initramfs\naris-core (PID 1)"]
    INIT --> EVN["evernight daemon"]
    EVN -->|"WebSocket TLS"| ENT["entelecheia"]

Integration with aris

kei delivers the kernel binary; aris packages it into a bootable image:

aris repository                     kei repository
─────────────────                   ─────────────────
packages/core/        supervisor    kernel/          kernel source
packages/builder/     image builder ostd/            core infra
overlay/              rootfs files  bsp/             board support
scripts/              build + flash board/           board configs
│                                    │
│  just build-board                  │  just build
│    ├── cross-compile aris-core     │    └── cargo build (aarch64)
│    ├── fetch kei-kernel.bin        │
│    ├── assemble image.img          │
│    └── just flash-sd /dev/sdX      │

Validate the integration:

# In aris repo: build with kei kernel
just build-board nanopi-r3s

# Boot in QEMU with the full image
just test-qemu

# Verify kei kernel version in boot log
grep "kei-kernel" output/boot.log

Troubleshooting

SymptomLikely CauseAction
No serial outputWrong baud rateUse 1500000, not 115200
GICv3 init failedQEMU machine typeUse virt,gic-version=3
SMP failedMissing PSCI in DTBCheck /cpus node in device tree
Kernel panicLLM-generated code artifactAudit ostd/src/arch/aarch64/
U-Boot can't find kernelWrong partition offsetVerify offset in boot.scr
evernight can't connectNetwork not configuredCheck /data/network.toml