Skip to main content

strat9_kernel/
components.rs

1//! Kernel component declarations — Strat9-OS boot orchestration.
2//!
3//! Each function annotated with `#[component::init_component]` is registered
4//! in the `.component_entries` linker section.  `component::init_all()` reads
5//! that section at runtime, topologically sorts the entries according to their
6//! `depends_on` edges (with `priority` as a tiebreaker), and calls them in order.
7//!
8//! ## Stages
9//!
10//! | Stage       | When                                    |
11//! |-------------|-----------------------------------------|
12//! | `bootstrap` | Before SMP, early kernel init           |
13//! | `kthread`   | After SMP, in kernel-thread context     |
14//! | `process`   | After first user process is created     |
15//!
16//! ## Syntax
17//!
18//! ```rust,no_run
19//! #[component::init_component(bootstrap, priority = 1)]
20//! fn vfs_init() -> Result<(), ComponentInitError> { … }
21//!
22//! #[component::init_component(kthread, priority = 2, depends_on = vfs_init)]
23//! fn fs_ext4_init() -> Result<(), ComponentInitError> { … }
24//!
25//! #[component::init_component(kthread, priority = 3, depends_on = [vfs_init, ipc_init])]
26//! fn silo_init() -> Result<(), ComponentInitError> { … }
27//! ```
28
29use component::ComponentInitError;
30
31// ============================================================================
32// Bootstrap stage — early kernel init (before SMP)
33// The `priority` tiebreaker applies only when two components have no ordering
34// edge between them; explicit `depends_on` edges take precedence.
35// ============================================================================
36
37/// Memory management — must be first; everything else implicitly depends on it.
38#[component::init_component(bootstrap, priority = 0)]
39fn memory_init() -> Result<(), ComponentInitError> {
40    log::info!("[component] Memory management initialized");
41    Ok(())
42}
43
44/// Logger — early debug output (needs memory for heap-backed ring-buffer).
45#[component::init_component(bootstrap, priority = 1, depends_on = memory_init)]
46fn logger_init() -> Result<(), ComponentInitError> {
47    log::info!("[component] Logger initialized");
48    Ok(())
49}
50
51/// Architecture primitives (GDT, IDT, TSS) — needs memory for TSS allocation.
52#[component::init_component(bootstrap, priority = 1, depends_on = memory_init)]
53fn arch_init() -> Result<(), ComponentInitError> {
54    log::info!("[component] Architecture primitives initialized");
55    Ok(())
56}
57
58/// Synchronization primitives — foundational, no deps beyond memory.
59#[component::init_component(bootstrap, priority = 2, depends_on = memory_init)]
60fn sync_init() -> Result<(), ComponentInitError> {
61    log::info!("[component] Sync primitives initialized");
62    Ok(())
63}
64
65/// ACPI and power management.
66#[component::init_component(bootstrap, priority = 3, depends_on = [memory_init, arch_init])]
67fn acpi_init() -> Result<(), ComponentInitError> {
68    log::info!("[component] ACPI initialized");
69    Ok(())
70}
71
72/// Capability-based security — needs memory; used by VFS and IPC.
73#[component::init_component(bootstrap, priority = 3, depends_on = memory_init)]
74fn capability_init() -> Result<(), ComponentInitError> {
75    log::info!("[component] Capability system initialized");
76    Ok(())
77}
78
79/// Virtual file system — needs memory and capability subsystem.
80#[component::init_component(bootstrap, priority = 4, depends_on = [memory_init, capability_init])]
81fn vfs_init() -> Result<(), ComponentInitError> {
82    log::info!("[component] VFS initialized");
83    Ok(())
84}
85
86/// IPC — inter-process communication primitives.
87#[component::init_component(bootstrap, priority = 4, depends_on = [memory_init, capability_init])]
88fn ipc_init() -> Result<(), ComponentInitError> {
89    log::info!("[component] IPC initialized");
90    Ok(())
91}
92
93/// Driver framework — needs arch primitives and memory.
94/// Hardware probing is deferred until paging + VFS are ready.
95#[component::init_component(bootstrap, priority = 5, depends_on = [memory_init, arch_init])]
96fn drivers_init() -> Result<(), ComponentInitError> {
97    log::info!("[component] Driver framework initialized");
98    Ok(())
99}
100
101// ============================================================================
102// Kthread stage — after SMP, in kernel-thread context
103// ============================================================================
104
105/// Process and task management — needs memory, arch, and the scheduler already
106/// running (guaranteed since kthread stage runs after schedule() is called).
107#[component::init_component(kthread, priority = 0)]
108fn process_init() -> Result<(), ComponentInitError> {
109    log::info!("[component] Process management initialized");
110    Ok(())
111}
112
113/// Namespace management — depends on VFS being ready (bootstrap stage).
114/// Cross-stage dep on `vfs_init` is skipped by the topo-sort (it's in a
115/// different stage) and is guaranteed by stage ordering.
116#[component::init_component(kthread, priority = 1, depends_on = process_init)]
117fn namespace_init() -> Result<(), ComponentInitError> {
118    log::info!("[component] Namespace management initialized");
119    Ok(())
120}
121
122/// Syscall interface — needs process + arch.
123#[component::init_component(kthread, priority = 1, depends_on = process_init)]
124fn syscall_init() -> Result<(), ComponentInitError> {
125    log::info!("[component] Syscall interface initialized");
126    Ok(())
127}
128
129/// Silo management — needs process + namespace + syscall.
130#[component::init_component(kthread, priority = 2, depends_on = [namespace_init, syscall_init])]
131fn silo_init() -> Result<(), ComponentInitError> {
132    log::info!("[component] Silo management initialized");
133    Ok(())
134}
135
136// ============================================================================
137// Process stage — after the first user process has been created
138// ============================================================================
139
140/// Network stack (userspace component stub).
141#[component::init_component(process, priority = 0)]
142fn network_init() -> Result<(), ComponentInitError> {
143    log::info!("[component] Network stack initialized");
144    Ok(())
145}
146
147/// Filesystem servers (userspace components).
148#[component::init_component(process, priority = 1, depends_on = network_init)]
149fn filesystem_init() -> Result<(), ComponentInitError> {
150    log::info!("[component] Filesystem servers initialized");
151    Ok(())
152}