mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 04:18:39 +08:00
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>
This commit is contained in:
parent
63249a070e
commit
549d3c2ffb
@ -56,6 +56,36 @@ use proc_macro::TokenStream;
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
|
/// ## Firmware
|
||||||
|
///
|
||||||
|
/// The following example shows how to declare a kernel module that needs
|
||||||
|
/// to load binary firmware files. You need to specify the file names of
|
||||||
|
/// the firmware in the `firmware` field. 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.
|
||||||
|
///
|
||||||
|
/// ```ignore
|
||||||
|
/// use kernel::prelude::*;
|
||||||
|
///
|
||||||
|
/// module!{
|
||||||
|
/// type: MyDeviceDriverModule,
|
||||||
|
/// name: "my_device_driver_module",
|
||||||
|
/// author: "Rust for Linux Contributors",
|
||||||
|
/// description: "My device driver requires firmware",
|
||||||
|
/// license: "GPL",
|
||||||
|
/// firmware: ["my_device_firmware1.bin", "my_device_firmware2.bin"],
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// struct MyDeviceDriverModule;
|
||||||
|
///
|
||||||
|
/// impl kernel::Module for MyDeviceDriverModule {
|
||||||
|
/// fn init() -> Result<Self> {
|
||||||
|
/// Ok(Self)
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
/// # Supported argument types
|
/// # Supported argument types
|
||||||
/// - `type`: type which implements the [`Module`] trait (required).
|
/// - `type`: type which implements the [`Module`] trait (required).
|
||||||
/// - `name`: ASCII string literal of the name of the kernel module (required).
|
/// - `name`: ASCII string literal of the name of the kernel module (required).
|
||||||
@ -63,6 +93,8 @@ use proc_macro::TokenStream;
|
|||||||
/// - `description`: string literal of the description of the kernel module.
|
/// - `description`: string literal of the description of the kernel module.
|
||||||
/// - `license`: ASCII string literal of the license of the kernel module (required).
|
/// - `license`: ASCII string literal of the license of the kernel module (required).
|
||||||
/// - `alias`: array of ASCII string literals of the alias names of the kernel module.
|
/// - `alias`: array of ASCII string literals of the alias names of the kernel module.
|
||||||
|
/// - `firmware`: array of ASCII string literals of the firmware files of
|
||||||
|
/// the kernel module.
|
||||||
#[proc_macro]
|
#[proc_macro]
|
||||||
pub fn module(ts: TokenStream) -> TokenStream {
|
pub fn module(ts: TokenStream) -> TokenStream {
|
||||||
module::module(ts)
|
module::module(ts)
|
||||||
|
@ -97,14 +97,22 @@ struct ModuleInfo {
|
|||||||
author: Option<String>,
|
author: Option<String>,
|
||||||
description: Option<String>,
|
description: Option<String>,
|
||||||
alias: Option<Vec<String>>,
|
alias: Option<Vec<String>>,
|
||||||
|
firmware: Option<Vec<String>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ModuleInfo {
|
impl ModuleInfo {
|
||||||
fn parse(it: &mut token_stream::IntoIter) -> Self {
|
fn parse(it: &mut token_stream::IntoIter) -> Self {
|
||||||
let mut info = ModuleInfo::default();
|
let mut info = ModuleInfo::default();
|
||||||
|
|
||||||
const EXPECTED_KEYS: &[&str] =
|
const EXPECTED_KEYS: &[&str] = &[
|
||||||
&["type", "name", "author", "description", "license", "alias"];
|
"type",
|
||||||
|
"name",
|
||||||
|
"author",
|
||||||
|
"description",
|
||||||
|
"license",
|
||||||
|
"alias",
|
||||||
|
"firmware",
|
||||||
|
];
|
||||||
const REQUIRED_KEYS: &[&str] = &["type", "name", "license"];
|
const REQUIRED_KEYS: &[&str] = &["type", "name", "license"];
|
||||||
let mut seen_keys = Vec::new();
|
let mut seen_keys = Vec::new();
|
||||||
|
|
||||||
@ -131,6 +139,7 @@ impl ModuleInfo {
|
|||||||
"description" => info.description = Some(expect_string(it)),
|
"description" => info.description = Some(expect_string(it)),
|
||||||
"license" => info.license = expect_string_ascii(it),
|
"license" => info.license = expect_string_ascii(it),
|
||||||
"alias" => info.alias = Some(expect_string_array(it)),
|
"alias" => info.alias = Some(expect_string_array(it)),
|
||||||
|
"firmware" => info.firmware = Some(expect_string_array(it)),
|
||||||
_ => panic!(
|
_ => panic!(
|
||||||
"Unknown key \"{}\". Valid keys are: {:?}.",
|
"Unknown key \"{}\". Valid keys are: {:?}.",
|
||||||
key, EXPECTED_KEYS
|
key, EXPECTED_KEYS
|
||||||
@ -186,6 +195,11 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream {
|
|||||||
modinfo.emit("alias", &alias);
|
modinfo.emit("alias", &alias);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if let Some(firmware) = info.firmware {
|
||||||
|
for fw in firmware {
|
||||||
|
modinfo.emit("firmware", &fw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Built-in modules also export the `file` modinfo string.
|
// Built-in modules also export the `file` modinfo string.
|
||||||
let file =
|
let file =
|
||||||
|
Loading…
Reference in New Issue
Block a user