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}