Building an OS in a New Language

May 2025 · 10 min read

When we built Lateralus, the question wasn't if we'd write an OS — it was when. A programming language proves itself at the edges: can it handle hardware interrupts? Can it manage memory without a runtime? Can it boot a machine? LateralusOS v1.0 answers yes to all three.

Why Write an OS?

Every systems language claims it can do low-level work. But claims aren't proof. Writing an actual bootable kernel forced us to solve real problems:

LateralusOS forced the language to grow. Features that seemed nice-to-have became essential.

Architecture Overview

LateralusOS v1.0 Components

The Kernel Entry Point

Here's how LateralusOS boots — the kernel entry point, written entirely in Lateralus:

// kernel/main.ltl — LateralusOS entry point
use kernel::{gdt, idt, pic, memory, drivers, shell}

fn kernel_main(boot_info: BootInfo) {
    boot_info
        |> gdt::init()
        |> idt::init()
        |> pic::init()

    let allocator = boot_info.memory_map
        |> memory::init_frame_allocator()

    let heap = allocator
        |> memory::init_heap(0x4444_0000, 1024 * 1024)

    drivers::init_all()
    shell::run()
}

The pipeline operator shines here. Kernel initialization is a sequence of dependent steps — exactly what pipelines model.

Memory Management

The physical frame allocator uses Lateralus's pattern matching to handle memory regions:

fn allocate_frame(allocator: &mut FrameAllocator) -> Option<Frame> {
    allocator.memory_map
        |> filter(|region| match region.kind {
            Usable     => true,
            Bootloader => false,
            Reserved   => false,
            _          => false,
        })
        |> flat_map(|r| r.start..r.end |> step_by(4096))
        |> find(|addr| !allocator.used.contains(addr))
        |> map(|addr| {
            allocator.used.insert(addr)
            Frame { address: addr }
        })
}

Interrupt Handling

Hardware interrupts need pattern matching — the CPU gives you an interrupt number, and you need to dispatch it fast:

fn interrupt_handler(frame: InterruptFrame, irq: u8) {
    match irq {
        0  => timer::tick(),
        1  => keyboard::handle_scancode(
            port::read_u8(0x60)
        ),
        14 => disk::handle_irq(),
        n  => println("Unhandled IRQ: {n}"),
    }
    pic::end_of_interrupt(irq)
}

The Shell

LateralusOS includes an interactive shell with pipeline support at the OS level:

// Built-in commands
fn execute(cmd: Command) {
    match cmd {
        Command::Help         => show_help(),
        Command::Clear        => vga::clear_screen(),
        Command::Ls(path)     => fs::list_dir(path),
        Command::Cat(path)    => fs::read_file(path) |> println(),
        Command::Echo(text)   => println(text),
        Command::Uptime       => timer::uptime() |> format_duration() |> println(),
        Command::MemInfo      => memory::stats() |> display(),
        Command::Shutdown     => acpi::shutdown(),
        Command::Unknown(s)   => println("Unknown: {s}"),
    }
}

Lessons Learned

Building LateralusOS taught us three things about language design:

  1. Pattern matching is essential for systems code. Hardware gives you numbers and flags — you need exhaustive matching to handle them safely.
  2. Pipelines work at every level. From kernel init to user shell commands, left-to-right data flow makes code clearer.
  3. Zero-cost abstractions matter. The pipeline operator compiles down to direct function calls — no runtime overhead in a kernel.

If your language can boot a computer, it can handle anything.

View LateralusOS on GitHub ← Back to Blog

What FRISC teaches

Every chapter of FRISC maps to a fundamental OS concept. Here's the curriculum in order:

Each chapter builds on the last. By chapter 8, you have a functional operating system with networking, a graphical desktop, and multicore support — all written in Lateralus, all running on bare RISC-V hardware.

FRISC by the numbers

Lateralus is built by bad-antics. Follow development on GitHub or try the playground.

What FRISC teaches

Every chapter of FRISC maps to a fundamental OS concept. Here's the curriculum in order:

Each chapter builds on the last. By chapter 8, you have a functional operating system with networking, a graphical desktop, and multicore support — all written in Lateralus, all running on bare RISC-V hardware.

FRISC by the numbers

Lateralus is built by bad-antics. Follow development on GitHub or try the playground.