kernel/initcall/driver.rs
1use crate::early_println;
2
3/// A macro used to register driver initialization functions to be called during the system boot process.
4///
5/// This macro places the function pointer into the `.initcall.driver` section of the binary,
6/// allowing the kernel to discover and call all driver initialization functions at the appropriate time.
7///
8/// # Parameters
9///
10/// * `$func` - A function with the signature `fn()` that register a driver
11///
12/// # Examples
13///
14/// ```
15/// fn register_my_driver() {
16/// // Driver registration logic here
17/// }
18///
19/// driver_initcall!(register_my_driver);
20/// ```
21///
22/// # Safety
23///
24/// This macro relies on linker sections and should only be used for functions that are
25/// safe to call during the kernel's driver initialization phase.
26///
27#[macro_export]
28macro_rules! driver_initcall {
29 ($func:ident) => {
30 #[unsafe(link_section = ".initcall.driver")]
31 #[used(linker)]
32 static __DRIVER_INITCALL__ : fn() = $func;
33 };
34}
35
36
37unsafe extern "C" {
38 static __INITCALL_DRIVER_START: usize;
39 static __INITCALL_DRIVER_END: usize;
40}
41
42pub fn driver_initcall_call() {
43 unsafe {
44 let size = core::mem::size_of::<fn()>();
45
46 early_println!("Running driver initcalls... ");
47 let mut func = &__INITCALL_DRIVER_START as *const usize as usize;
48 let end = &__INITCALL_DRIVER_END as *const usize as usize;
49 let num = (end - func) / size;
50
51 for i in 0..num {
52 early_println!("Driver initcalls {} / {}", i + 1, num);
53 let initcall = *(func as *const fn());
54 initcall();
55 func += size;
56 }
57 }
58}