reef-os Library
Part of: Reef Language Reference Last reviewed on version: 0.8.0 Status: Implemented
Overview
reef-os is a specialized library for operating system and kernel development in Reef. It provides low-level primitives that don't belong in the standard library.
Key Features:
- CPU control (halt, interrupt enable/disable, I/O ports)
- Memory barriers and cache operations
- Control registers and MSRs
- Spinlock synchronization
- Serial port debugging
- Limine boot protocol support
Supported Architectures:
| Architecture | Module | Status |
|---|---|---|
| x86-64 (AMD64) | cpu.x86_64 |
Implemented |
| ARM64 (AArch64) | cpu.aarch64 |
Implemented |
| RISC-V 64 | Future | Planned |
Setup
Environment Variable
Set REEF_OS_PATH to use reef-os modules:
export REEF_OS_PATH=/path/to/reef-os
Import Modules
import cpu.x86_64 as cpu
import drivers.serial as serial
import boot.limine as limine
import sync.spinlock as spinlock
Module: cpu.x86_64
CPU Control
proc halt() // HLT - wait for interrupt
proc cli() // Clear interrupt flag (disable interrupts)
proc sti() // Set interrupt flag (enable interrupts)
proc pause() // Spin-wait hint
proc nop() // No operation
I/O Ports
fn inb(port: uint16): uint8 // Read byte from port
fn inw(port: uint16): uint16 // Read word from port
fn inl(port: uint16): uint32 // Read dword from port
proc outb(port: uint16, value: uint8) // Write byte to port
proc outw(port: uint16, value: uint16) // Write word to port
proc outl(port: uint16, value: uint32) // Write dword to port
Memory Barriers
proc mfence() // Full memory fence
proc lfence() // Load fence
proc sfence() // Store fence
Control Registers
fn read_cr0(): uint64
fn read_cr2(): uint64 // Page fault linear address
fn read_cr3(): uint64 // Page directory base
fn read_cr4(): uint64
proc write_cr0(value: uint64)
proc write_cr3(value: uint64)
proc write_cr4(value: uint64)
Model Specific Registers
fn rdmsr(msr: uint32): uint64
proc wrmsr(msr: uint32, value: uint64)
Miscellaneous
fn read_rflags(): uint64
proc invlpg(addr: uint64) // Invalidate TLB entry
Module: cpu.aarch64
CPU Control
proc wfi() // Wait for interrupt
proc wfe() // Wait for event
proc sev() // Send event
proc yield_cpu() // Yield to other threads
proc nop() // No operation
Interrupts
proc disable_interrupts()
proc enable_interrupts()
Memory Barriers
proc dmb_sy() // Data memory barrier (full system)
proc dmb_ish() // Data memory barrier (inner shareable)
proc dsb_sy() // Data synchronization barrier (full)
proc dsb_ish() // Data synchronization barrier (inner)
proc isb() // Instruction synchronization barrier
Cache Operations
proc dc_civac(addr: uint64) // Clean and invalidate by VA to PoC
proc dc_cvac(addr: uint64) // Clean by VA to PoC
proc ic_iallu() // Invalidate all instruction caches
TLB Operations
proc tlbi_alle1() // Invalidate all TLB entries EL1
proc tlbi_vae1(addr: uint64) // Invalidate TLB entry by VA EL1
System Registers
Functions to read/write system registers:
- MPIDR_EL1 (processor affinity)
- CurrentEL (current exception level)
- SCTLR_EL1 (system control)
- TTBR0_EL1, TTBR1_EL1 (translation table base)
- TCR_EL1 (translation control)
- ESR_EL1 (exception syndrome)
- FAR_EL1 (fault address)
- VBAR_EL1 (vector base address)
Module: drivers.serial
COM Port Constants
fn COM1(): uint16 // 0x3F8
fn COM2(): uint16 // 0x2F8
fn COM3(): uint16 // 0x3E8
fn COM4(): uint16 // 0x2E8
Initialization
proc initialize(port: uint16)
Status
fn is_transmit_empty(port: uint16): bool
fn is_data_ready(port: uint16): bool
Character I/O
proc write_char(port: uint16, c: char)
fn read_char(port: uint16): char
String I/O
proc write_string(port: uint16, s: string)
proc write_line(port: uint16, s: string) // Adds newline
Hex Output
proc write_hex8(port: uint16, value: uint8)
proc write_hex16(port: uint16, value: uint16)
proc write_hex32(port: uint16, value: uint32)
proc write_hex64(port: uint16, value: uint64)
Module: sync.spinlock
API
proc acquire(lock: pointer) // Blocking acquire
proc release(lock: pointer) // Release lock
fn try_acquire(lock: pointer): bool // Non-blocking attempt
Implementation
Uses atomic compare-and-swap:
- AMD64:
LOCK CMPXCHG - ARM64:
LDXR/STXRwith exclusive monitors
Module: boot.limine
Memory Map Entry Types
fn LIMINE_MEMMAP_USABLE(): uint64
fn LIMINE_MEMMAP_RESERVED(): uint64
fn LIMINE_MEMMAP_ACPI_RECLAIMABLE(): uint64
fn LIMINE_MEMMAP_ACPI_NVS(): uint64
fn LIMINE_MEMMAP_BAD_MEMORY(): uint64
fn LIMINE_MEMMAP_BOOTLOADER_RECLAIMABLE(): uint64
fn LIMINE_MEMMAP_KERNEL_AND_MODULES(): uint64
fn LIMINE_MEMMAP_FRAMEBUFFER(): uint64
Framebuffer Memory Models
fn LIMINE_FRAMEBUFFER_RGB(): uint8
Example: Minimal Kernel
import cpu.x86_64 as cpu
import drivers.serial as serial
import boot.limine as limine
proc kernel_main()
// Initialize serial for debug output
serial.initialize(serial.COM1())
serial.write_line(serial.COM1(), "Reef OS starting...")
// Read CPU state
serial.write_string(serial.COM1(), "CR0: 0x")
serial.write_hex64(serial.COM1(), cpu.read_cr0())
serial.write_line(serial.COM1(), "")
serial.write_string(serial.COM1(), "CR3: 0x")
serial.write_hex64(serial.COM1(), cpu.read_cr3())
serial.write_line(serial.COM1(), "")
serial.write_line(serial.COM1(), "Halting...")
halt_loop()
end kernel_main
proc halt_loop()
cpu.cli()
loop
cpu.halt()
end loop
end halt_loop
proc main()
kernel_main()
end main
Building a Kernel
1. Type Check
REEF_OS_PATH=/path/to/reef-os reefc examples/minimal_kernel.reef --check
2. Generate C Code
REEF_OS_PATH=/path/to/reef-os reefc --emit-c examples/minimal_kernel.reef
3. Complete Kernel Requirements
A bootable kernel also needs:
- Limine bootloader and
limine.conf - Linker script for kernel memory layout
- Limine request structures (C or assembly)
- ISO creation script
See Limine examples for complete setups.
Directory Structure
reef-os/
├── cpu/
│ ├── x86_64.reef # AMD64 CPU primitives
│ └── aarch64.reef # ARM64 CPU primitives
├── drivers/
│ └── serial.reef # UART serial driver
├── boot/
│ └── limine.reef # Limine boot protocol
├── sync/
│ └── spinlock.reef # Spinlock implementation
└── examples/
└── minimal_kernel.reef
Design Notes
Why a Separate Library?
OS development code is specialized and doesn't belong in the standard library:
- Privileged instructions only work in kernel mode
- No process isolation or safety guarantees
- Different memory model (no GC, manual allocation)
Limine Bootloader
Reef targets Limine because:
- Modern 64-bit bootloader
- Handles x86 mode switches and paging setup
- Simple protocol with well-defined structures
- Active development and documentation