@@ -160,7 +160,7 @@ fn build_modinfo_string_param(module: &str, field: &str, param: &str, content: &
160160/// The `type` argument should be a type which implements the [`KernelModule`] trait.
161161/// Also accepts various forms of kernel metadata.
162162///
163- /// Example:
163+ /// ## Example
164164/// ```rust,no_run
165165/// use kernel::prelude::*;
166166///
@@ -170,17 +170,36 @@ fn build_modinfo_string_param(module: &str, field: &str, param: &str, content: &
170170/// author: b"Rust for Linux Contributors",
171171/// description: b"My very own kernel module!",
172172/// license: b"GPL v2",
173- /// params: {},
173+ /// params: {
174+ /// my_i32: i32 {
175+ /// default: 42,
176+ /// permissions: 0o644,
177+ /// description: b"Example of i32",
178+ /// },
179+ /// },
174180/// }
175181///
176182/// struct MyKernelModule;
177183///
178184/// impl KernelModule for MyKernelModule {
179185/// fn init() -> KernelResult<Self> {
186+ /// println!("i32 param is: {}", my_i32.read());
180187/// Ok(MyKernelModule)
181188/// }
182189/// }
183190/// ```
191+ ///
192+ /// ## Suported Parameter Types
193+ ///
194+ /// - `bool` - Corresponds to C `bool` param type.
195+ /// - `u8` - Corresponds to C `char` param type.
196+ /// - `i16` - Corresponds to C `short` param type.
197+ /// - `u16` - Corresponds to C `ushort` param type.
198+ /// - `i32` - Corresponds to C `int` param type.
199+ /// - `u32` - Corresponds to C `uint` param type.
200+ /// - `u64` - Corresponds to C `ullong` param type.
201+ /// - `invbool` - Corresponds to C `invbool` param type. Value is inverse of user input.
202+ /// - `str` - Corresponds to C `charp` param type. `read` signature is `read(&self) -> Result<&str, core::str::Utf8Error>`.
184203#[ proc_macro]
185204pub fn module ( ts : TokenStream ) -> TokenStream {
186205 let mut it = ts. into_iter ( ) ;
@@ -215,10 +234,10 @@ pub fn module(ts: TokenStream) -> TokenStream {
215234 assert_eq ! ( group. delimiter( ) , Delimiter :: Brace ) ;
216235
217236 let mut param_it = group. stream ( ) . into_iter ( ) ;
218- let param_default = if param_type == "bool" {
219- get_ident ( & mut param_it, "default" )
220- } else {
221- get_literal ( & mut param_it, "default" )
237+ let param_default = match param_type. as_ref ( ) {
238+ "bool" | "invbool" => get_ident ( & mut param_it, "default" ) ,
239+ "str" => get_byte_string ( & mut param_it , "default" ) ,
240+ _ => get_literal ( & mut param_it, "default" ) ,
222241 } ;
223242 let param_permissions = get_literal ( & mut param_it, "permissions" ) ;
224243 let param_description = get_byte_string ( & mut param_it, "description" ) ;
@@ -228,7 +247,14 @@ pub fn module(ts: TokenStream) -> TokenStream {
228247 // TODO: other kinds: arrays, unsafes, etc.
229248 let param_kernel_type = match param_type. as_ref ( ) {
230249 "bool" => "bool" ,
250+ "u8" => "char" ,
251+ "i16" => "short" ,
252+ "u16" => "ushort" ,
231253 "i32" => "int" ,
254+ "u32" => "uint" ,
255+ "u64" => "ullong" ,
256+ "invbool" => "invbool" ,
257+ "str" => "charp" ,
232258 t => panic ! ( "Unrecognized type {}" , t) ,
233259 } ;
234260
@@ -244,18 +270,59 @@ pub fn module(ts: TokenStream) -> TokenStream {
244270 & param_name,
245271 & param_description,
246272 ) ) ;
273+ let param_type_internal = match param_type. as_ref ( ) {
274+ "str" => "*mut u8" ,
275+ "invbool" => "bool" ,
276+ _ => & param_type,
277+ } ;
278+ let param_default = match param_type. as_ref ( ) {
279+ "str" => format ! ( "b\" {}\0 \" as *const u8 as *mut u8" , param_default) ,
280+ _ => param_default,
281+ } ;
282+ let read_func = match param_type. as_ref ( ) {
283+ "str" => format ! (
284+ "
285+ fn read(&self) -> Result<&str, core::str::Utf8Error> {{
286+ unsafe {{
287+ let mut count = 0;
288+ while *__{name}_{param_name}_value.add(count) != b'\0 ' {{
289+ count += 1;
290+ }}
291+ core::str::from_utf8(&core::slice::from_raw_parts(__{name}_{param_name}_value, count))
292+ }}
293+ }}
294+ " ,
295+ name = name,
296+ param_name = param_name,
297+ ) ,
298+ _ => format ! (
299+ "
300+ fn read(&self) -> {param_type_internal} {{
301+ unsafe {{ __{name}_{param_name}_value }}
302+ }}
303+ " ,
304+ name = name,
305+ param_name = param_name,
306+ param_type_internal = param_type_internal,
307+ ) ,
308+ } ;
309+ let kparam = format ! (
310+ "
311+ kernel::bindings::kernel_param__bindgen_ty_1 {{
312+ arg: unsafe {{ &__{name}_{param_name}_value }} as *const _ as *mut kernel::c_types::c_void,
313+ }},
314+ " ,
315+ name = name,
316+ param_name = param_name,
317+ ) ;
247318 params_modinfo. push_str (
248319 & format ! (
249320 "
250- static mut __{name}_{param_name}_value: {param_type } = {param_default};
321+ static mut __{name}_{param_name}_value: {param_type_internal } = {param_default};
251322
252323 struct __{name}_{param_name};
253324
254- impl __{name}_{param_name} {{
255- fn read(&self) -> {param_type} {{
256- unsafe {{ __{name}_{param_name}_value }}
257- }}
258- }}
325+ impl __{name}_{param_name} {{ {read_func} }}
259326
260327 const {param_name}: __{name}_{param_name} = __{name}_{param_name};
261328
@@ -288,17 +355,17 @@ pub fn module(ts: TokenStream) -> TokenStream {
288355 perm: {permissions},
289356 level: -1,
290357 flags: 0,
291- __bindgen_anon_1: kernel::bindings::kernel_param__bindgen_ty_1 {{
292- arg: unsafe {{ &__{name}_{param_name}_value }} as *const _ as *mut kernel::c_types::c_void,
293- }},
358+ __bindgen_anon_1: {kparam}
294359 }});
295360 " ,
296361 name = name,
297- param_type = param_type,
362+ param_type_internal = param_type_internal,
363+ read_func = read_func,
298364 param_kernel_type = param_kernel_type,
299365 param_default = param_default,
300366 param_name = param_name,
301367 permissions = param_permissions,
368+ kparam = kparam,
302369 )
303370 ) ;
304371 }
0 commit comments