Subsystems

Memory, execution, DIS scheduler, init, relocation, userspace, and early boot.

Documentation

Memory Subsystem

The memory subsystem (helix-memory, 12 files, ~2,200 lines) manages all physical and virtual memory from early boot through full runtime.

Architecture

Memory Subsystem — Architecture5N · 4E
AddressSpacePer-process virtual …1PageTableMapperArchitecture-generic…2HeapAllocator / GlobalHeapKernel heap (GlobalA…2PhysicalMemoryManagerGlobal PMM2RegionManager + ProtectionDomainRAM / ROM / Device /…1
100%
☝ Drag to pan·🤏 Pinch to zoom·Tap a node

Core Types

subsystems/memory/src/lib.rs
rust
pub struct Frame {
2
address: PhysAddr, // Physical address of the frame
3
size: PageSize, // Size (4K / 2M / 1G)
4
}
5
pub struct Page {
7
address: VirtAddr, // Virtual address of the page
8
size: PageSize, // Size (4K / 2M / 1G)
9
}
10
pub enum MemoryZone {
12
Dma, // 0-16 MB (ISA DMA)
13
Dma32, // 0-4 GB (32-bit device DMA)
14
Normal, // 4 GB+ (general purpose)
15
High, // Above addressable range
16
Device, // Memory-mapped I/O
17
}
Index

Physical Allocators

AllocatorAlgorithmBlock SizeUse Case
BumpAllocatorLinear bump pointer4 KB framesEarly boot only — fast, never frees
BitmapAllocatorBit-per-frame bitmap4 KB framesGeneral allocation — find_free, zone support
BuddyAllocatorBuddy system4 KB → 8 MBLarge contiguous allocations — MAX_ORDER=11

The BuddyAllocator splits and merges power-of-2 sized blocks:

Buddy Allocator — Order Sizes8N · 7E
mergemergemergemergemerge...mergeOrder 04 KB (1 page)1Order 18 KB (2 pages)2Order 216 KB (4 pages)2Order 332 KB2Order 464 KB2Order 5128 KB2Order 104 MB (1024 pages)2Order 118 MB (2048 pages)1
100%
☝ Drag to pan·🤏 Pinch to zoom·Tap a node

When a 16 KB allocation is requested, the allocator finds the smallest available block >= 16 KB and splits larger blocks in half until the right size is reached. When freed, adjacent buddies are merged back together.

Slab Allocator

For kernel heap allocations (small objects), the SlabAllocator provides 8 size classes:

ClassObject SizeSlab Layout
016 bytesFree-list of 16B cells
132 bytesFree-list of 32B cells
264 bytesFree-list of 64B cells
3128 bytesFree-list of 128B cells
4256 bytesFree-list of 256B cells
5512 bytesFree-list of 512B cells
61024 bytesFree-list of 1KB cells
72048 bytesFree-list of 2KB cells

Each size class maintains a linked list of slabs. Allocation is O(1) — pop from the free list. Objects larger than 2 KB fall through to the buddy allocator.

Virtual Memory

subsystems/memory/src/virtual_memory/mod.rs
rust
pub trait VirtualMapper: Send + Sync {
fn map(&self, page: Page, frame: Frame, flags: PageFlags) -> MemResult<()>;
fn unmap(&self, page: Page) -> MemResult<Frame>;
fn translate(&self, virt: VirtAddr) -> Option<PhysAddr>;
fn update_flags(&self, page: Page, flags: PageFlags) -> MemResult<()>;
fn flush(&self, page: Page);
fn flush_all(&self);
8
}
9
10
bitflags! {
3 refs
pub struct PageFlags: u64 {
12
const PRESENT = 1 << 0;
13
const WRITABLE = 1 << 1;
14
const USER = 1 << 2;
15
const WRITE_THROUGH = 1 << 3;
16
const NO_CACHE = 1 << 4;
17
const ACCESSED = 1 << 5;
18
const DIRTY = 1 << 6;
19
const HUGE = 1 << 7;
20
const GLOBAL = 1 << 8;
21
const NO_EXECUTE = 1 << 63;
22
}
23
}
Index

Address Space

Each process gets its own AddressSpace providing POSIX-like memory operations:

subsystems/memory/src/virtual_memory/address_space.rs
rust
impl AddressSpace {
pub fn mmap_anonymous(&self, addr: Option<VirtAddr>,
3
size: usize, flags: PageFlags) -> MemResult<VirtAddr>;
pub fn munmap(&self, addr: VirtAddr, size: usize) -> MemResult<()>;
pub fn mprotect(&self, addr: VirtAddr, size: usize,
6
flags: PageFlags) -> MemResult<()>;
pub fn brk(&self, new_brk: VirtAddr) -> MemResult<VirtAddr>;
8
}
Index

Region management detects overlaps and automatically splits/merges adjacent regions with compatible flags.

Memory Protection

subsystems/memory/src/protection.rs
rust
pub struct ProtectionDomain {
2
pub key: ProtectionKey, // Intel PKU key (0-15)
3
pub flags: ProtectionFlags,
4
}
5
6
bitflags! {
2 refs
pub struct ProtectionFlags: u32 {
8
const NONE = 0;
9
const READ = 1 << 0;
10
const WRITE = 1 << 1;
11
const EXECUTE = 1 << 2;
12
const RW = Self::READ.bits() | Self::WRITE.bits();
13
const RX = Self::READ.bits() | Self::EXECUTE.bits();
14
const RWX = Self::RW.bits() | Self::EXECUTE.bits();
15
}
16
}
Index

GuardPage: Unmapped pages placed around kernel stacks to catch stack overflows. A page fault on a guard page triggers an immediate panic with a clear stack overflow message.


Execution

The execution subsystem (helix-execution, 12 files, ~2,500 lines) manages threads, processes, scheduling, and context switching.

Thread Model

subsystems/execution/src/thread/thread.rs
rust
pub struct Thread {
2
id: ThreadId,
3
process: ProcessId,
4
name: String,
5
state: AtomicU32, // ThreadState
6
priority: spin::RwLock<Priority>,
7
flags: spin::RwLock<ThreadFlags>,
8
context: spin::Mutex<ThreadContext>,
9
kernel_stack: KernelStack, // 16 KiB
10
affinity: spin::RwLock<u64>, // CPU bitmask
11
cpu: spin::RwLock<Option<usize>>,
12
exit_code: spin::RwLock<Option<i32>>,
13
}
14
15
#[repr(u32)]
2 refs
pub enum ThreadState {
17
Creating = 0, // Being set up
18
Ready = 1, // Runnable, waiting for CPU
19
Running = 2, // Currently executing
20
Blocked = 3, // Waiting for event/resource
21
Sleeping = 4, // Timed wait
22
Stopped = 5, // Stopped by signal/debugger
23
Dead = 6, // Fully cleaned up
24
Zombie = 7, // Terminated, not yet reaped
25
}
Index

ThreadContext

The hardware context saved/restored during context switches:

subsystems/execution/src/thread/thread.rs
rust
pub struct ThreadContext {
2
pub ip: u64, // Instruction pointer
3
pub sp: u64, // Stack pointer
4
pub regs: [u64; 16], // General-purpose registers
5
pub flags: u64, // CPU flags (RFLAGS on x86)
6
}
Index

FPU state is saved lazily — only when a thread that used FPU/SSE/AVX is switched out and another thread needs FPU. This avoids the cost of saving 512+ bytes of XMM/YMM registers on every context switch.

Scheduler

subsystems/execution/src/scheduler/traits.rs
rust
pub trait Scheduler: Send + Sync {
fn name(&self) -> &'static str;
fn version(&self) -> &'static str;
fn init(&mut self, cpu_count: usize) -> ExecResult<()>;
fn pick_next(&self, cpu: usize) -> Option<ThreadId>;
fn add_thread(&self, thread: SchedulableThread) -> ExecResult<()>;
fn remove_thread(&self, id: ThreadId) -> ExecResult<()>;
fn thread_ready(&self, id: ThreadId) -> ExecResult<()>;
fn thread_block(&self, id: ThreadId) -> ExecResult<()>;
fn yield_thread(&self, cpu: usize);
fn tick(&self, cpu: usize);
fn set_priority(&self, id: ThreadId, priority: Priority) -> ExecResult<()>;
fn needs_reschedule(&self, cpu: usize) -> bool;
fn stats(&self) -> SchedulerStats;
15
}
Index

Three scheduling queue types are available:

QueueAlgorithmUse Case
FifoQueueFirst-in-first-outRound-robin scheduling
PriorityQueuePriority-sortedReal-time threads
MultilevelQueueMultiple priority bandsGeneral purpose

Priority System

subsystems/execution/src/scheduler.rs
rust
8 refs
pub struct Priority(pub u8); // 0-139
2
8 refs
impl Priority {
pub const REALTIME_THRESHOLD: u8 = 100;
pub const IDLE: Priority = Priority(0);
pub const LOW: Priority = Priority(30);
pub const NORMAL: Priority = Priority(60);
pub const HIGH: Priority = Priority(90);
pub const REALTIME: Priority = Priority(120);
pub const CRITICAL: Priority = Priority(139);
11
}
Index

Threads with priority >= 100 are treated as real-time and always preempt non-real-time threads.

Context Switch

subsystems/execution/src/context.rs
rust
2 refs
pub struct ContextSwitchEngine {
2
fpu_lazy: AtomicBool,
3
hooks: spin::RwLock<Vec<Arc<dyn ContextSwitchHook>>>,
4
}
5
2 refs
impl ContextSwitchEngine {
pub fn add_hook(&self, hook: Arc<dyn ContextSwitchHook>);
pub unsafe fn switch(
9
&self, from: ThreadId, to: ThreadId,
10
from_ctx: &mut ThreadContext, to_ctx: &ThreadContext,
11
reason: SwitchReason,
12
);
13
}
14
2 refs
pub enum SwitchReason {
16
Yield, // Voluntary yield
17
Preemption, // Timer quantum expired
18
Blocked, // Waiting for resource
19
Exit, // Thread terminating
20
Interrupt, // Interrupt handling
21
NewThread, // New thread started
22
}
Index

Hooks are called before and after each context switch, enabling:

  • Statistics collection — track CPU time per thread
  • TLS switching — update thread-local storage pointer
  • FPU lazy switching — save FPU state only when needed
  • Performance counters — reset per-thread PMC values

Process Model

subsystems/execution/src/process.rs
rust
pub struct Process {
2
id: ProcessId,
3
parent: Option<ProcessId>,
4
name: String,
5
state: AtomicU32, // ProcessState
6
main_thread: RwLock<Option<ThreadId>>,
7
threads: RwLock<Vec<ThreadId>>,
8
children: RwLock<Vec<ProcessId>>,
9
exit_code: RwLock<Option<i32>>,
10
}
11
2 refs
pub enum ProcessState {
13
Creating, Running, Stopped, Zombie, Dead,
14
}
Index

Execution Domains

subsystems/execution/src/domains.rs
rust
2 refs
pub enum DomainType {
2
Kernel, // Ring 0, full privileges
3
User, // Ring 3, standard process
4
Driver, // May be ring 0 or separate
5
Sandbox, // Restricted user
6
}
7
pub struct ExecutionDomain {
9
id: DomainId,
10
name: String,
11
domain_type: DomainType,
12
threads: RwLock<BTreeSet<ThreadId>>,
13
processes: RwLock<BTreeSet<ProcessId>>,
14
}
Index

DIS Scheduler

The Dynamic Intent Scheduling system (helix-dis, 12 files, ~11,600 lines) is Helix's unique scheduling approach that schedules tasks based on intent rather than just priority.

Core Concept

Instead of assigning a static priority, each task declares an intent describing what it's trying to accomplish. The DIS engine uses this intent to make scheduling decisions, adjust time slices, and optimize for the workload:

subsystems/dis/intent.rs
rust
1
#[repr(u8)]
pub enum IntentClass {
3
RealTime = 0, // Audio, video — strict deadlines
4
SoftRealTime = 1, // UI rendering — best-effort deadlines
5
Interactive = 2, // User-facing — low latency
6
Server = 3, // Request-response — throughput
7
Batch = 4, // Data processing — CPU-bound
8
Background = 5, // Maintenance — lowest priority
9
Idle = 6, // Run only when nothing else needs CPU
10
Critical = 7, // Kernel services — highest priority
11
}
Index

Intent Specification

subsystems/dis/intent.rs
rust
pub struct Intent {
2
pub id: IntentId,
3
pub class: IntentClass,
4
pub flags: IntentFlags,
5
pub latency: LatencyTarget,
6
pub cpu_budget: CpuBudget,
7
pub memory_budget: MemoryBudget,
8
pub io_budget: IoBudget,
9
}
10
2 refs
pub struct CpuBudget {
12
pub quota: Duration, // Max CPU time per period
13
pub period: Duration, // Budget period
14
}
Index

Intent Presets

DIS provides built-in presets for common workloads:

PresetIntent ClassTime SliceCPU Affinity
audio_playbackRealTime1 msPreferred single core
video_renderingRealTime2 msAny
ui_threadInteractive4 msPreferred BSP
web_serverServer10 msAny
databaseServer8 msNUMA-aware
compilationBatch50 msAll cores
backupBackground100 msAny
gcBackground20 msAny
monitoringIdle200 msAny

Queue Architecture

DIS integrates 7 queue levels into a unified scheduling framework:

DIS — Queue Levels7N · 6E
fallthroughfallthroughfallthroughfallthroughfallthroughfallthroughLevel 0: RealTimeDeadlineQueue1Level 1: SoftRealTimeDeadlineQueue2Level 2: InteractiveFairQueue2Level 3: ServerFairQueue2Level 4: BatchMultilevelFeedbackQu…2Level 5: BackgroundMultilevelFeedbackQu…2Level 6: IdleFIFO1
100%
☝ Drag to pan·🤏 Pinch to zoom·Tap a node

The IntegratedQueues struct manages all seven levels. On each tick, the scheduler picks the highest-priority non-empty queue and selects the next task from it.

Prediction Engine

DIS includes a machine-learning-based prediction engine that learns from task behavior:

subsystems/dis/optimizer.rs
rust
pub struct PredictionEngine {
pub fn predict_runtime(&self, task: &TaskDescriptor) -> Duration;
pub fn predict_memory(&self, task: &TaskDescriptor) -> usize;
pub fn suggest_strategy(&self, task: &TaskDescriptor) -> OptimizationHint;
pub fn learn(&mut self, task: &TaskDescriptor, actual: &TaskStatistics);
6
}
Index

Optimization strategies include:

  • TimeSlice — adjust quantum based on predicted runtime
  • Priority — boost/demote based on behavior pattern
  • Affinity — pin to optimal CPU based on cache locality
  • Energy — consolidate tasks for power saving

Security Integration

DIS enforces isolation at the scheduling level:

subsystems/dis/isolation.rs
rust
pub struct SecurityDomain {
2
pub id: DomainId,
3
pub name: String,
4
pub domain_type: DomainType,
5
pub default_caps: CapabilitySet,
6
pub isolation: IsolationLevel,
7
pub limits: ResourceLimits,
8
}
9
2 refs
pub enum DomainType {
11
Kernel, System, User, Service, Sandbox, Guest, Container,
12
}
13
2 refs
pub enum IsolationLevel {
15
None, // No isolation — kernel threads
16
Light, // Basic process isolation
17
Standard, // Full memory protection
18
Strict, // Verified IPC only
19
Paranoid, // Maximum restrictions, minimal capabilities
20
}
Index

44 distinct capabilities are managed via a 128-bit bitmap for O(1) permission checks.

Statistics and Monitoring

subsystems/dis/stats.rs
rust
pub struct TaskStats {
2
pub cpu_time: Nanoseconds,
3
pub user_time: Nanoseconds,
4
pub kernel_time: Nanoseconds,
5
pub wait_time: Nanoseconds,
6
pub io_wait_time: Nanoseconds,
7
pub context_switches: u64,
8
pub voluntary_switches: u64,
9
pub involuntary_switches: u64,
10
pub preemptions: u64,
11
pub migrations: u64,
12
pub peak_memory: u64,
13
}
14
pub enum BehaviorPattern {
16
CpuBound, IoBound, Mixed, Bursty,
17
Periodic, EventDriven, Latency, Throughput,
18
}
Index

The StatsCollector performs anomaly analysis — detecting tasks that deviate from expected behavior patterns and flagging them for policy review.


Init Subsystem

The init subsystem (helix-init, 23 files, ~4,500 lines) manages the kernel's 5-phase boot sequence.

Phase Definitions

subsystems/init/src/phase.rs
rust
pub enum InitPhase {
2
Boot = 0, // Firmware handoff, serial console
3
Early = 1, // GDT, IDT, heap, physical memory
4
Core = 2, // Interrupts, timers, scheduler
5
Late = 3, // Drivers, filesystem, IPC
6
Runtime = 4, // Userspace, modules, networking
7
}
Index

Phase Capabilities

Each phase unlocks new capabilities tracked via bitflags:

subsystems/init/src/phase.rs
rust
1
bitflags! {
pub struct PhaseCapabilities: u32 {
3
const CONSOLE = 1 << 0;
4
const HEAP = 1 << 1;
5
const MEMORY = 1 << 2;
6
const INTERRUPTS = 1 << 3;
7
const SCHEDULER = 1 << 4;
8
const TIMERS = 1 << 5;
9
const IPC = 1 << 6;
10
const DRIVERS = 1 << 7;
11
const FILESYSTEM = 1 << 8;
12
const USERSPACE = 1 << 9;
13
const MODULES = 1 << 10;
14
const NETWORK = 1 << 11;
15
}
16
}
Index

A subsystem can only be initialized if all its required capabilities are available. The init framework enforces this at runtime.

Subsystem Registration

subsystems/init/src/subsystem.rs
rust
pub struct SubsystemInfo {
2
pub name: &'static str,
3
pub phase: InitPhase,
4
pub priority: u32, // Within-phase ordering
5
pub dependencies: Vec<&'static str>,
6
pub capabilities: PhaseCapabilities, // What this provides
7
pub requires: PhaseCapabilities, // What this needs
8
}
9
pub trait Subsystem: Send + Sync {
2 refs
fn name(&self) -> &'static str;
fn init(&mut self) -> Result<()>;
fn start(&mut self) -> Result<()>;
fn stop(&mut self) -> Result<()>;
fn health_check(&self) -> HealthStatus;
fn state(&self) -> SubsystemState;
2 refs
fn dependencies(&self) -> &[&'static str];
2 refs
fn capabilities(&self) -> PhaseCapabilities;
19
}
20
2 refs
pub enum SubsystemState {
22
Registered, Initializing, Running, Stopping,
23
Stopped, Failed, Recovering,
24
}
Index

13 Init Subsystems

SubsystemPhasePriorityProvidesDependencies
boot00CONSOLENone
cpu110boot
debug120boot
memory130HEAP, MEMORYcpu
interrupts240INTERRUPTSmemory
timers250TIMERSinterrupts
scheduler260SCHEDULERtimers, memory
ipc370IPCscheduler
drivers380DRIVERSinterrupts, memory
filesystem385FILESYSTEMdrivers, memory
security390memory, ipc
network4100NETWORKdrivers, ipc
userland4110USERSPACE, MODULESfilesystem, security, scheduler

Relocation

The relocation subsystem (helix-relocation, 12 files, ~2,000 lines, edition 2024) handles ELF binary relocation for KASLR and PIE kernel images.

Purpose

When the kernel is built as a Position-Independent Executable (PIE), all absolute addresses in the binary must be adjusted when the kernel is loaded at a different address than it was linked for. This adjustment is called relocation.

Components

Relocation — Source Tree10N · 9E
helix-relocation/src/ELF relocation engin…9lib.rsPublic API, Relocati…1elf.rsELF header/section/s…1relocations.rsRelocation entry pro…1sections.rsSection header itera…1symbols.rsSymbol table lookup1kaslr.rsKASLR entropy + offs…1validation.rsPost-relocation inte…1arch/Architecture-specifi…1boot_context.rsBoot information for…1
100%
☝ Drag to pan·🤏 Pinch to zoom·Tap a node

Relocation Process

  1. Parse ELF headers from the kernel image
  2. Read the .dynamic section to find .rela.dyn and .rela.plt
  3. Generate KASLR offset from entropy source
  4. Apply each relocation: *(target) = base + addend + kaslr_offset
  5. Validate: ensure all relocated pointers fall within the kernel image
  6. Jump to the relocated kernel entry point

Userspace

The userspace subsystem (helix-userspace, 8 files, ~3,500 lines) provides the bridge between kernel services and user programs.

ELF Loader

subsystems/userspace/src/elf.rs
rust
2 refs
pub struct ElfLoader;
2
2 refs
impl ElfLoader {
pub fn parse(data: &[u8]) -> Result<ParsedElf>;
pub fn load(parsed: &ParsedElf, address_space: &mut AddressSpace) -> Result<LoadedElf>;
6
}
7
3 refs
pub struct ParsedElf {
9
pub header: ElfHeader,
10
pub program_headers: Vec<ProgramHeader>,
11
pub section_headers: Vec<SectionHeader>,
12
pub symbols: Vec<Symbol>,
13
pub entry_point: u64,
14
pub is_pie: bool,
15
}
Index

The loader supports:

  • ELF64 format (little-endian)
  • PT_LOAD segments for code and data
  • PT_INTERP for dynamic linking (future)
  • PIE (Position-Independent Executables)
  • Section headers for debug info and symbols

Runtime

subsystems/userspace/src/runtime.rs
rust
pub struct Runtime {
pub fn spawn(&mut self, program: &Program,
3
args: &[&str], env: &Environment) -> Result<ProcessHandle>;
pub fn kill(&mut self, pid: ProcessId, signal: Signal) -> Result<()>;
pub fn reap(&mut self, pid: ProcessId) -> Result<ExitStatus>;
6
}
7
2 refs
pub struct ProcessHandle {
9
pub pid: ProcessId,
10
pub state: ProcessState,
11
pub fd_table: FdTable,
12
}
13
2 refs
pub enum ProcessState {
15
Created, Running, Blocked, Stopped, Zombie, Dead,
16
}
Index

File Descriptor Table

subsystems/userspace/src/fd.rs
rust
2 refs
pub struct FdTable {
2
entries: BTreeMap<Fd, FdEntry>,
3
next_fd: Fd,
4
}
5
2 refs
impl FdTable {
pub fn new() -> Self; // Pre-opens stdin(0), stdout(1), stderr(2)
pub fn alloc(&mut self, entry: FdEntry) -> Result<Fd>;
pub fn close(&mut self, fd: Fd) -> Result<()>;
pub fn dup(&mut self, old_fd: Fd) -> Result<Fd>;
pub fn get(&self, fd: Fd) -> Option<&FdEntry>;
12
}
Index

Shell

The built-in kernel shell provides 16 commands:

CommandDescription
helpList all commands
exitExit the shell
echo <text>Print text to stdout
clearClear the screen
psList running processes and threads
memDisplay memory statistics
uptimeShow kernel uptime
unamePrint kernel name and version
set <key>=<val>Set environment variable
historyShow command history
benchRun benchmarks
statsDisplay system statistics
cat <file>Print file contents
run <program>Execute an ELF binary
versionPrint detailed version info
demoRun kernel demonstration

The shell supports ANSI color output, command history, and an ASCII art banner on startup.

Syscall Interface

The userspace crate implements 47 syscalls (42 POSIX-compatible + 5 Helix-specific):

POSIX Syscalls:

NumberNameDescription
0readRead from file descriptor
1writeWrite to file descriptor
2openOpen file
3closeClose file descriptor
4statGet file status
9mmapMap memory
10mprotectChange memory protection
11munmapUnmap memory
12brkChange data segment size
39getpidGet process ID
57forkCreate child process
59execveExecute program
60exitTerminate process
62killSend signal

Helix-Specific Syscalls:

NumberNameDescription
500helix_dis_statsGet DIS scheduler statistics
501helix_hot_reloadTrigger module hot-reload
502helix_self_healTrigger subsystem recovery
503helix_benchmarkRun kernel benchmarks
504helix_kernel_infoGet kernel version and state

Syscall ABI

subsystems/userspace/src/syscall.rs
rust
pub struct SyscallArgs {
2
pub number: usize, // rax
3
pub arg0: usize, // rdi
4
pub arg1: usize, // rsi
5
pub arg2: usize, // rdx
6
pub arg3: usize, // r10
7
pub arg4: usize, // r8
8
pub arg5: usize, // r9
9
}
10
// Return value in rax. Error: negative errno.
Index

Early Boot

The early boot path bridges the gap between the bootloader and the full kernel. This code runs before the heap, interrupts, or scheduler are available.

Minimal Profile Entry

The helix-minimal-os crate (profiles/minimal/main.rs, ~1,700 lines) is the kernel entry point:

profiles/minimal/src/main.rs
rust
1
#[no_mangle]
2
pub extern "C" fn kernel_main(boot_info: &BootInfo) -> ! {
3
// Phase 0: Boot
4
serial::init();
5
kprintln!("Helix OS v{}", VERSION);
6
7
// Phase 1: Early
8
heap::init(HEAP_BASE, HEAP_SIZE); // 4 MB initial heap
9
memory::init(boot_info.memory_map());
10
11
// Phase 2: Core
12
interrupts::init();
13
timer::init();
14
scheduler::init();
15
16
// Phase 3: Late
17
fs::mount_helixfs();
18
19
// Phase 4: Runtime
20
modules::load_all();
21
userspace::init();
22
23
// Demos
24
demo_hot_reload();
25
demo_self_healing();
26
demo_ai_cortex();
27
demo_benchmarks();
28
demo_shell();
29
30
// Event loop
31
loop { halt(); }
32
}

Boot Protocols

ProtocolEntry SymbolBoot InfoPaging
Liminelimine_entryLimine Protocol Rev 2 requestsHigher-half provided
Multiboot2_startMultiboot2 info structureMust set up manually
UEFIefi_mainUEFI System TableIdentity-mapped, must remap

Each protocol provides a memory map, framebuffer info, RSDP pointer, and command line. The early boot code normalizes this into a common BootConfiguration.