Repository navigation
Artery target
Artery is a from-scratch Rust kernel written alongside Lamina. Its architecture lists Lamina as one compiler backend among several and keeps it at arm's length: an external, versioned dependency, never something the OS requires. Any language targeting Artery stays free to use LLVM, GCC, or an interpreter instead.
For Lamina the arrangement is useful in the other direction. Artery is the hardest freestanding target on the list, so getting it working is a good check on whether the backend functions outside a hosted environment at all.
TargetOperatingSystem::Artery exists behind the nightly feature. The driver reads
artery as an OS name and prints it back. That is all of it. No code generation, no
object emission, no linking path. Everything below is planned work.
Artery builds for x86_64 and aarch64, under constraints a hosted backend never meets.
| Constraint | What it means for code generation |
|---|---|
| Freestanding | No libc, no CRT startup objects, no dynamic loader. The entry point is whatever the linker script names |
| Soft float | x86_64 with SSE and AVX off; aarch64 with NEON off and strict alignment on. Correct code without touching the vector units |
| No red zone | Interrupt handling makes it unusable, so nothing may sit below the stack pointer |
| Abort on panic | No unwinding, so no unwind tables are needed and none should be required |
| Script-driven layout | Section placement comes from a linker script, not from linker defaults |
Artery loads a container format of its own rather than parsing ELF in the kernel. An ELF parser sitting on the untrusted-input path in ring 0 is a security cost the project decided not to pay. Compatibility comes from a converter instead: a packing tool turns an ELF file into the container.
So Lamina does not need to write that container. A correct freestanding ELF is enough, and the packer handles the rest. Two things follow for code generation. A segment that is both writable and executable cannot be represented in the target format, so nothing Lamina emits may need one. And the capability requests a program declares are added by the packer, not by the compiler.
Artery's system call surface lives in its ABI crate. A Lamina-compiled program should reach it by declaring and calling those entry points, not by having the backend emit system call instructions against a hardcoded convention.
This is the same fix as the Windows bug in 0.1. Both come from an I/O intrinsic whose fallback path assumes Linux, and both need external function declarations. Doing it once covers both.
| ID | Item | Depends on |
|---|---|---|
| A1 | Wire x86_64_artery and aarch64_artery through target parsing, the codegen support tables, and ELF object selection |
0.2 codegen trait |
| A2 | Soft-float code generation and ABI on both architectures | 0.4 |
| A3 | Red-zone-free and strict-alignment code generation | 0.4 |
| A4 | Freestanding link: -T and -static in weld, a driver profile that adds no CRT and no interpreter, no writable-executable segments |
0.2, 0.4 |
| A5 | System calls through extern declarations against the Artery ABI | #7 |
| A6 | A packing step in the driver, so building for an Artery target produces a loadable container | A1 to A4 |
A program compiled by Lamina, packed into the container format, loads and runs on an Artery kernel booted under QEMU.
Not when it builds, and not when a test passes. A green build of an artifact that never executes measures the parts and not the whole.
Artery's compiler plan goes further than a triple: a C subset frontend on Lamina, an Oxygen frontend using the JIT, a frontend SDK with a stable IR builder and a diagnostics API, and later building user-space tools with Lamina to compare the output against Clang and GCC.
Those are Artery's milestones, not Lamina's. What they need from this side is the stable IR construction API, diagnostics transport, source-location metadata, and debug-information interfaces described in 0.3 and 1.0.
lamina · ras · weld · lamina-web