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 let size = core::mem::size_of::<fn()>();
38
39 println!("Running initcalls... ");
40 let mut func = unsafe { &__INITCALL_DRIVER_END as *const usize as usize };
41 let end = unsafe { &__INITCALL_END as *const usize as usize };
42 let num = (end - func) / size;
43
44 for i in 0..num {
45 println!("Initcalls {} / {}", i + 1, num);
46 let initcall = unsafe { *(func as *const fn()) };
47 initcall();
48 func += size;
49 }
50
51 println!("Initcalls done.");
52}