在 Linux 新版内核中的 Rust 初探,原来是这样的!( 二 )


struct RustMinimal {
numbers: Vec
,
}
它是一个包含 32 位整数值的 Vec 。本身 Rust 允许为结构类型添加接口("trait")实现 。因此 , 这个示例模块为 RustMinimal 类型实现了 kernel::Module trait 。
impl kernel::Module for RustMinimal {
fn init(_module: &'static ThisModule) -> Result
{
pr_info!("Rust minimal sample (init)n");
pr_info!("Am I built-in? {}n", !cfg!(MODULE));
let mut numbers = Vec::new();
numbers.try_push(72)?;
numbers.try_push(108)?;
numbers.try_push(200)?;
Ok(RustMinimal { numbers })
}
}
这个 init() 函数常常被认为是做常规模块初始化的工作 。但在这种情况下 , 被期望做常规的模块初始化工作 。在这种情况下 , 它向系统日志做了一些反馈(在这个过程中 , 它通过 cfg!()宏 , 可以在编译时用于查询内核配置参数) 。然后 , 它分配了一个可变的 Vec , 并试图将三个数字放入其中 。try_push() 的使用在这里很重要:一个 Vec 会在必要时调整自己的大小 。这涉及到分配内存 , 这在内核环境中可能会失败 。
如果分配失败 , try_push() 将返回一个失败的状态 , 这反过来将导致 init() 返回失败(这就是代码行最后"?"的作用) 。
那么 , 如果一切顺利 , 它会返回一个 RustMinimal 结构 , 其中包含分配的 Vec 和一个成功状态 。由于这个模块没有与任何其他内核子系统交互 , 实际上它不会做任何事情 , 只是耐心地等待被删除 。在 Kernel::Module trait 中没有移除模块的函数;相反 , 这里使用一个简单的 RustMinimal 类型的析构器 。
impl Drop for RustMinimal {
fn drop(&mut self) {
pr_info!("My numbers are {:?}n", self.numbers);
pr_info!("Rust minimal sample (exit)n");
}
}
这个函数打印出初始化时存储在 Vec 中的数字(从而确认数据在此期间存活)并返回 , 之后 , 该模块将被删除 , 其内存被释放 。似乎没有办法让模块删除失败 。
 
 
最后在最后 , Jonathan Corbet 说道 , 这就是在 Linux 6.1 中可以对 Rust 内核模块所做的事情的大致范围 。这是一个可以玩的东西 , 但它目前还不能用于任何形式的真正的内核编程 。
他表示 , “希望这种情况在不久的将来会有所改变 。如果幸运的话 , Linux 6.2 版内核中的 Rust 将大大增强能力 。”
来源:https://lwn.NET/SubscriberLink/910762/a26f968ea086e32d/




推荐阅读