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}