An ARM64 language and compiler for making low-level behavior explicit and inspectable.
Conformance tests, byte-identical kernel builds, fuzzing, and QEMU fixtures check the work. I own the language and compiler decisions; AI assists implementation.
My day job is building web interfaces; Wyst scratches my low-level programming itch and puts my CS degree to use.
ARM64-onlypre-1.0Rust bootstrap compilernot memory-safepronounced “wist,” an old word meaning “to know”
/** QEMU `virt` is a generic virtual Arm board.* Its PL011 UART provides serial text output.** UART registers are memory-mapped I/O (MMIO):* reads and writes at these addresses reach a* device rather than ordinary RAM.** A register address is UART0's base plus its* PL011 byte offset. QEMU maps UART0's base at* 0x0900_0000.*/register_mapPl011 {
// DR is the data register.// DATA is its eight-bit transmit payload.DR: writeonlyu32at0x00 {
DATA: u8at0..=7
}
// FR is the flag register.// TXFF means the transmit FIFO is full.FR: readonlyu32at0x18 {
TXFF: boolat5
}
}
mmioUART0: Pl011at0x0900_0000/** There is no process runtime to call `main`. The* layout file, similar to a linker script, names* `_start` as the entry point. QEMU jumps here after* loading the kernel image.** QEMU passes a device-tree blob (DTB) address in Arm* register `x0`; it describes the virtual hardware.* `naked` omits the usual function prologue because* no valid stack exists yet. `never` records that* there is no caller to return to.*/// Put the entry address on a 16-byte boundary.
#[align(16)]
pubnakedfn_start(dtb: @u8 in x0) -> never {
// __stack_top is a linker-style symbol from the layout.// Set the CPU stack pointer to that reserved RAM.asm establishes stack (
stack: u64 in x1 =__stack_top,
) {
mov sp, stack
}
// The stack is ready, so ordinary function calls are safe.kernel_main(dtb)
}
fnuart_write(byte: u8) {
// Poll for space in the transmit FIFO.whileUART0.FR.read().TXFF {
cpu.nop()
}
UART0.DR.write(DATA=byte)
}
fnuart_hello() {
// UART output is byte-oriented.constmsg: [6]u8= ['h', 'e', 'l', 'l', 'o', '\n']
// #len is compile-time metadata;// the array has no runtime length field.fori in 0 ..< #len(msg) {
uart_write(msg[i])
}
}
fnkernel_main(dtb: @u8) -> never {
// Production code would parse the DTB.// This fixture only checks that the handoff supplied it.ifdtb==address<@u8>(0) {
test_exit(0x63)
}
uart_hello()
// Bare metal has no caller to return to. `test_exit`// plays the role of process exit for this QEMU test:// report status 0, then stop the virtual machine.
test_exit(0)
}