Module Selection

How to choose, configure, and write modules for your Helix kernel profile.

Documentation

ModuleTrait v2

Every pluggable component in Helix — schedulers, allocators, filesystems, drivers — is a module. The ModuleTrait v2 is the recommended API for new modules, providing lifecycle management, event handling, health monitoring, and state persistence for hot-reload.

modules/src/v2/mod.rs
rust
pub trait ModuleTrait: Send + Sync {
fn info(&self) -> ModuleInfo; // REQUIRED
fn init(&mut self, ctx: &Context) -> Result<(), ModuleError>; // REQUIRED
fn start(&mut self) -> Result<(), ModuleError>; // REQUIRED
fn stop(&mut self) -> Result<(), ModuleError>; // REQUIRED
6
7
// Optional — override for custom behavior
fn handle_event(&mut self, _event: &Event) -> EventResponse {
9
EventResponse::Ignored
10
}
fn handle_request(&mut self, _request: &Request) -> Result<Response, ModuleError> {
12
Ok(Response::err("Not implemented"))
13
}
fn is_healthy(&self) -> bool { true }
fn save_state(&self) -> Option<Vec<u8>> { None }
fn restore_state(&mut self, _state: &[u8]) -> Result<(), ModuleError> { Ok(()) }
17
}
Index

Module Info

Module metadata is declared with a const builder pattern. This means module info is computed at compile time — no runtime overhead.

modules/src/v2/mod.rs
rust
2 refs
pub struct ModuleInfo {
2
pub name: &'static str,
3
pub version: ModuleVersion,
4
pub description: &'static str,
5
pub author: &'static str,
6
pub license: &'static str,
7
pub flags: ModuleFlags,
8
pub dependencies: &'static [&'static str],
9
pub provides: &'static [&'static str],
10
}
11
12
// Const builder — all computed at compile time
2 refs
impl ModuleInfo {
14
pub const fn new(name: &'static str) -> Self;
15
pub const fn version(self, major: u16, minor: u16, patch: u16) -> Self;
16
pub const fn description(self, desc: &'static str) -> Self;
17
pub const fn author(self, author: &'static str) -> Self;
18
pub const fn flags(self, flags: ModuleFlags) -> Self;
19
pub const fn dependencies(self, deps: &'static [&'static str]) -> Self;
20
pub const fn provides(self, caps: &'static [&'static str]) -> Self;
21
}
Index

Module Flags

Flags control module behavior and capabilities. Combine them with bitwise OR. When selecting modules for your profile, these flags determine how the module integrates with the kernel.

FlagBitDescription
ESSENTIAL1 << 0Cannot be unloaded — kernel panics if it fails
HOT_RELOADABLE1 << 1Supports live replacement without restarting
USERSPACE1 << 2Runs in user ring (ring 3)
DRIVER1 << 3Hardware driver module
FILESYSTEM1 << 4Filesystem implementation
SCHEDULER1 << 5Scheduler implementation
ALLOCATOR1 << 6Memory allocator module
SECURITY1 << 7Security policy module
EXPERIMENTAL1 << 8Unstable — testing only

Events & Requests

Modules receive events from the kernel and can handle requests from other modules. This is the primary communication mechanism between modules.

modules/src/v2/mod.rs
rust
pub enum Event {
2
Tick { timestamp_ns: u64 },
3
Shutdown,
4
MemoryPressure { level: MemoryPressureLevel },
5
CpuHotplug { cpu_id: u32, online: bool },
6
Custom { name: String, data: Vec<u8> },
7
}
8
pub enum EventResponse { Handled, Ignored, Error(String) }
10
pub struct Request {
12
pub source: &'static str,
13
pub request_type: String,
14
pub payload: Vec<u8>,
15
}
16
2 refs
pub struct Response {
18
pub success: bool,
19
pub payload: Vec<u8>,
20
pub error: Option<String>,
21
}
22
2 refs
impl Response {
pub fn ok(payload: Vec<u8>) -> Self;
pub fn ok_empty() -> Self;
pub fn err(message: impl Into<String>) -> Self;
27
}
Index

Choosing Modules

When configuring your kernel profile, you select modules in the [modules] section of helix.toml:

profiles/my-kernel/helix.toml
toml
1
[modules]
2
# Static modules — linked into the kernel binary at build time
3
static = ["helix-scheduler-round-robin"]
4
5
# Dynamic modules — loaded at runtime (requires dynamic loader)
6
dynamic = []

Available Module Categories

CategoryInterfaceCurrent Implementations
Schedulerhelix.schedulerhelix-scheduler-round-robin
Allocatorhelix.allocatorBuilt-in bump + slab allocators
Filesystemhelix.filesystemHelixFS (built-in)
Block Devicehelix.block_devicePlanned
Networkhelix.networkPlanned
Securityhelix.securityPlanned
GPU Driverhelix.gpuMagma (planned)

Module Discovery

Modules that provide the same interface can be discovered at runtime through the interface registry:

modules/src/interfaces.rs
rust
1
// Standard interface names
pub mod interfaces {
pub const SCHEDULER: &str = "helix.scheduler";
pub const ALLOCATOR: &str = "helix.allocator";
pub const FILESYSTEM: &str = "helix.filesystem";
pub const BLOCK_DEVICE: &str = "helix.block_device";
pub const NETWORK: &str = "helix.network";
pub const SECURITY: &str = "helix.security";
9
}
10
11
// Discover modules implementing an interface
12
let schedulers = interface_registry().get_implementors("helix.scheduler");
13
let primary = interface_registry().get_primary("helix.scheduler");
Index

Writing a Module for Your Profile

Here's a full, working module that implements a custom scheduler:

modules_impl/my_scheduler/src/lib.rs
rust
1
#![no_std]
2
extern crate alloc;
3
4
use helix_modules::v2::*;
5
use helix_modules::{ModuleError, ModuleFlags};
6
2 refs
pub struct MyScheduler {
8
initialized: bool,
9
task_count: u64,
10
}
11
2 refs
impl ModuleTrait for MyScheduler {
fn info(&self) -> ModuleInfo {
14
ModuleInfo::new("my-scheduler")
15
.version(1, 0, 0)
16
.description("Custom round-robin scheduler")
17
.author("Developer")
18
.flags(ModuleFlags::SCHEDULER | ModuleFlags::HOT_RELOADABLE)
19
.dependencies(&["helix-execution"])
20
.provides(&["scheduler", "cpu.scheduling"])
21
}
22
fn init(&mut self, ctx: &Context) -> Result<(), ModuleError> {
24
let _time_slice = ctx.config_or("time_slice_ms", "10");
25
self.initialized = true;
26
Ok(())
27
}
28
fn start(&mut self) -> Result<(), ModuleError> { Ok(()) }
fn stop(&mut self) -> Result<(), ModuleError> { Ok(()) }
31
fn handle_event(&mut self, event: &Event) -> EventResponse {
33
match event {
34
Event::Tick { .. } => {
35
self.task_count += 1;
36
EventResponse::Handled
37
}
38
_ => EventResponse::Ignored,
39
}
40
}
41
fn is_healthy(&self) -> bool { self.initialized }
43
}
Index

For the full module system documentation — registry, dependency resolution, interface system, and macros — see the Module System docs page.