kernel/initcall/mod.rs
1//! # Initcall System
2//!
3//! The initcall module manages the kernel's initialization sequence by providing
4//! a structured way to execute initialization functions at different stages of boot.
5//!
6//! ## Submodules
7//!
8//! - `early`: Initialization functions that need to run early in the boot process
9//! - `driver`: Driver initialization routines
10//! - `late`: Initialization functions that should run late in the boot process
11//!
12//! ## Initcall Mechanism
13//!
14//! The initcall system works by collecting function pointers between special linker
15//! sections (`__INITCALL_START` and `__INITCALL_END`). Each function pointer
16//! represents an initialization function that needs to be called during boot.
17//!
18//! The `initcall_task()` function iterates through these function pointers and
19//! executes each initialization routine in sequence, providing progress updates
20//! to the console. After all initialization routines have been executed, the
21//! processor enters an idle state.
22
23use crate::println;
24
25pub mod early;
26pub mod driver;
27pub mod late;
28
29#[allow(improper_ctypes)]
30unsafe extern "C" {
31 static mut __INITCALL_DRIVER_END: usize;
32 static mut __INITCALL_END: usize;
33}
34
35#[allow(static_mut_refs)]
36pub fn call_initcalls() {
37 unsafe {
38 let size = core::mem::size_of::<fn()>();
39
40 println!("Running initcalls... ");
41 let mut func_addr = &__INITCALL_DRIVER_END as *const usize as usize;
42 let end_addr = &__INITCALL_END as *const usize as usize;
43
44 while func_addr < end_addr {
45 let initcall = core::ptr::read_volatile(func_addr as *const fn());
46 initcall();
47 func_addr += size;
48 }
49 }
50}