@@ -25,131 +25,6 @@ pub mod user_ptr;
2525pub use crate :: error:: { Error , KernelResult } ;
2626pub use crate :: types:: { CStr , Mode } ;
2727
28- /// Declares the entrypoint for a kernel module. The first argument should be a type which
29- /// implements the [`KernelModule`] trait. Also accepts various forms of kernel metadata.
30- ///
31- /// Example:
32- /// ```rust,no_run
33- /// use kernel::prelude::*;
34- ///
35- /// struct MyKernelModule;
36- /// impl KernelModule for MyKernelModule {
37- /// fn init() -> KernelResult<Self> {
38- /// Ok(MyKernelModule)
39- /// }
40- /// }
41- ///
42- /// kernel_module!(
43- /// MyKernelModule,
44- /// author: b"Rust for Linux Contributors",
45- /// description: b"My very own kernel module!",
46- /// license: b"GPL"
47- /// );
48- #[ macro_export]
49- macro_rules! kernel_module {
50- ( $module: ty, $( $name: ident : $value: expr) ,* ) => {
51- static mut __MOD: Option <$module> = None ;
52-
53- // Built-in modules are initialized through an initcall pointer
54- //
55- // TODO: should we compile a C file on the fly to avoid duplication?
56- #[ cfg( not( MODULE ) ) ]
57- #[ cfg( not( CONFIG_HAVE_ARCH_PREL32_RELOCATIONS ) ) ]
58- #[ link_section = ".initcall6.init" ]
59- #[ used]
60- pub static __initcall: extern "C" fn ( ) -> $crate:: c_types:: c_int = init_module;
61-
62- #[ cfg( not( MODULE ) ) ]
63- #[ cfg( CONFIG_HAVE_ARCH_PREL32_RELOCATIONS ) ]
64- global_asm!(
65- r#".section ".initcall6.init", "a"
66- __initcall:
67- .long init_module - .
68- .previous
69- "#
70- ) ;
71-
72- // TODO: pass the kernel module name here to generate a unique,
73- // helpful symbol name (the name would also useful for the `modinfo`
74- // issue below).
75- #[ no_mangle]
76- pub extern "C" fn init_module( ) -> $crate:: c_types:: c_int {
77- match <$module as $crate:: KernelModule >:: init( ) {
78- Ok ( m) => {
79- unsafe {
80- __MOD = Some ( m) ;
81- }
82- return 0 ;
83- }
84- Err ( e) => {
85- return e. to_kernel_errno( ) ;
86- }
87- }
88- }
89-
90- #[ no_mangle]
91- pub extern "C" fn cleanup_module( ) {
92- unsafe {
93- // Invokes drop() on __MOD, which should be used for cleanup.
94- __MOD = None ;
95- }
96- }
97-
98- $(
99- $crate:: kernel_module!( @attribute $name, $value) ;
100- ) *
101- } ;
102-
103- // TODO: The modinfo attributes below depend on the compiler placing
104- // the variables in order in the .modinfo section, so that you end up
105- // with b"key=value\0" in order in the section. This is a reasonably
106- // standard trick in C, but I'm not sure that rustc guarantees it.
107- //
108- // Ideally we'd be able to use concat_bytes! + stringify_bytes! +
109- // some way of turning a string literal (or at least a string
110- // literal token) into a bytes literal, and get a single static
111- // [u8; * N] with the whole thing, but those don't really exist yet.
112- // Most of the alternatives (e.g. .as_bytes() as a const fn) give
113- // you a pointer, not an array, which isn't right.
114-
115- // TODO: `modules.builtin.modinfo` etc. is missing the prefix (module name)
116- ( @attribute author, $value: expr) => {
117- #[ link_section = ".modinfo" ]
118- #[ used]
119- pub static AUTHOR_KEY : [ u8 ; 7 ] = * b"author=" ;
120- #[ link_section = ".modinfo" ]
121- #[ used]
122- pub static AUTHOR_VALUE : [ u8 ; $value. len( ) ] = * $value;
123- #[ link_section = ".modinfo" ]
124- #[ used]
125- pub static AUTHOR_NUL : [ u8 ; 1 ] = * b"\0 " ;
126- } ;
127-
128- ( @attribute description, $value: expr) => {
129- #[ link_section = ".modinfo" ]
130- #[ used]
131- pub static DESCRIPTION_KEY : [ u8 ; 12 ] = * b"description=" ;
132- #[ link_section = ".modinfo" ]
133- #[ used]
134- pub static DESCRIPTION_VALUE : [ u8 ; $value. len( ) ] = * $value;
135- #[ link_section = ".modinfo" ]
136- #[ used]
137- pub static DESCRIPTION_NUL : [ u8 ; 1 ] = * b"\0 " ;
138- } ;
139-
140- ( @attribute license, $value: expr) => {
141- #[ link_section = ".modinfo" ]
142- #[ used]
143- pub static LICENSE_KEY : [ u8 ; 8 ] = * b"license=" ;
144- #[ link_section = ".modinfo" ]
145- #[ used]
146- pub static LICENSE_VALUE : [ u8 ; $value. len( ) ] = * $value;
147- #[ link_section = ".modinfo" ]
148- #[ used]
149- pub static LICENSE_NUL : [ u8 ; 1 ] = * b"\0 " ;
150- } ;
151- }
152-
15328/// KernelModule is the top level entrypoint to implementing a kernel module. Your kernel module
15429/// should implement the `init` method on it, which maps to the `module_init` macro in Linux C API.
15530/// You can use this method to do whatever setup or registration your module should do. For any
0 commit comments