Writing U-mode Apps
How it works
userapp.aero (Aero code)
↓ aero compiler --emit-obj --target riscv64-unknown-none
userapp.o (RISC-V object)
↓ aero-ld + linker.ld → AeroOS-26R1-riscv64.elf
Kernel image (S-mode + U-mode linked together)
↓ QEMU -kernel → OpenSBI → kernel_start
scheduler_create2(userapp_main, 1)
↓ timer interrupt / sret
userapp_main() runs in U-mode!
Key concept: 26R1 has no filesystem. U-mode programs are not independent ELFs — they compile to .o and link with the S-mode kernel into one image. This is single-address-space design.
Minimal Example
myapp.aero:
extern "C" fn sys_write(s: str, n: i64) -> i64;
extern "C" fn sys_yield();
#[no_mangle]
fn myapp_main() {
let mut count = 0;
loop {
sys_write("hello from myapp\n", 17);
count = count + 1;
sys_yield();
}
}
Known Limitations (26R1)
| Limitation | Reason | Fix |
|---|---|---|
| No inline asm | Aero v1.2.4 | 26R2+ or C shims |
| No stdlib | Bare-metal kernel | Lightweight lib needed |
| No U-mode malloc | No heap allocator exposed | P2+ |
| No filesystem | No initrd / virtio-blk | 26R3 or 27 |
| No PMP protection | OpenSBI allows all | Security-driven |