Skip to content

Commit 549d3c2

Browse files
fujitaojeda
authored andcommitted
rust: add 'firmware' field support to module! macro
This adds 'firmware' field support to module! macro, corresponds to MODULE_FIRMWARE macro. You can specify the file names of binary firmware that the kernel module requires. The information is embedded in the modinfo section of the kernel module. For example, a tool to build an initramfs uses this information to put the firmware files into the initramfs image. Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com> Reviewed-by: Benno Lossin <benno.lossin@proton.me> Link: https://lore.kernel.org/r/20240501123548.51769-1-fujita.tomonori@gmail.com Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
1 parent 63249a0 commit 549d3c2

File tree

2 files changed

+48
-2
lines changed

2 files changed

+48
-2
lines changed

rust/macros/lib.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,45 @@ use proc_macro::TokenStream;
5656
/// }
5757
/// ```
5858
///
59+
/// ## Firmware
60+
///
61+
/// The following example shows how to declare a kernel module that needs
62+
/// to load binary firmware files. You need to specify the file names of
63+
/// the firmware in the `firmware` field. The information is embedded
64+
/// in the `modinfo` section of the kernel module. For example, a tool to
65+
/// build an initramfs uses this information to put the firmware files into
66+
/// the initramfs image.
67+
///
68+
/// ```ignore
69+
/// use kernel::prelude::*;
70+
///
71+
/// module!{
72+
/// type: MyDeviceDriverModule,
73+
/// name: "my_device_driver_module",
74+
/// author: "Rust for Linux Contributors",
75+
/// description: "My device driver requires firmware",
76+
/// license: "GPL",
77+
/// firmware: ["my_device_firmware1.bin", "my_device_firmware2.bin"],
78+
/// }
79+
///
80+
/// struct MyDeviceDriverModule;
81+
///
82+
/// impl kernel::Module for MyDeviceDriverModule {
83+
/// fn init() -> Result<Self> {
84+
/// Ok(Self)
85+
/// }
86+
/// }
87+
/// ```
88+
///
5989
/// # Supported argument types
6090
/// - `type`: type which implements the [`Module`] trait (required).
6191
/// - `name`: ASCII string literal of the name of the kernel module (required).
6292
/// - `author`: string literal of the author of the kernel module.
6393
/// - `description`: string literal of the description of the kernel module.
6494
/// - `license`: ASCII string literal of the license of the kernel module (required).
6595
/// - `alias`: array of ASCII string literals of the alias names of the kernel module.
96+
/// - `firmware`: array of ASCII string literals of the firmware files of
97+
/// the kernel module.
6698
#[proc_macro]
6799
pub fn module(ts: TokenStream) -> TokenStream {
68100
module::module(ts)

rust/macros/module.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,14 +97,22 @@ struct ModuleInfo {
9797
author: Option<String>,
9898
description: Option<String>,
9999
alias: Option<Vec<String>>,
100+
firmware: Option<Vec<String>>,
100101
}
101102

102103
impl ModuleInfo {
103104
fn parse(it: &mut token_stream::IntoIter) -> Self {
104105
let mut info = ModuleInfo::default();
105106

106-
const EXPECTED_KEYS: &[&str] =
107-
&["type", "name", "author", "description", "license", "alias"];
107+
const EXPECTED_KEYS: &[&str] = &[
108+
"type",
109+
"name",
110+
"author",
111+
"description",
112+
"license",
113+
"alias",
114+
"firmware",
115+
];
108116
const REQUIRED_KEYS: &[&str] = &["type", "name", "license"];
109117
let mut seen_keys = Vec::new();
110118

@@ -131,6 +139,7 @@ impl ModuleInfo {
131139
"description" => info.description = Some(expect_string(it)),
132140
"license" => info.license = expect_string_ascii(it),
133141
"alias" => info.alias = Some(expect_string_array(it)),
142+
"firmware" => info.firmware = Some(expect_string_array(it)),
134143
_ => panic!(
135144
"Unknown key \"{}\". Valid keys are: {:?}.",
136145
key, EXPECTED_KEYS
@@ -186,6 +195,11 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream {
186195
modinfo.emit("alias", &alias);
187196
}
188197
}
198+
if let Some(firmware) = info.firmware {
199+
for fw in firmware {
200+
modinfo.emit("firmware", &fw);
201+
}
202+
}
189203

190204
// Built-in modules also export the `file` modinfo string.
191205
let file =

0 commit comments

Comments
 (0)