关注了就能看到更多这么棒的文章哦~
Resources for learning Rust for kernel development
By Daroc Alden
September 23, 2024
Kangrejos 2024
Gemini-1.5-flash translation
https://lwn.net/Articles/990619/
Dirk Behme 在 Kangrejos 2024 上紧随 他关于错误处理的会议 之后主持了第二个会议,主题是讨论如何为内核 Rust 抽象的用户提供更好的指导。紧随其后,Carlos Bilbao 和 Miguel Ojeda 有他们自己的时间段,专门用于收集对想要快速了解内核 Rust 开发的人有用的资源。与会者在两场会议中都提供了很多指导,并讨论了他们可以做些什么来让来自非 Rust 背景的人更容易上手。
他从指出“你们大多数人都是专家”开始演讲 — 与会者大多已经熟悉 Rust。他们编写了驱动程序,发现缺少抽象,并编写了抽象。所以几乎会议室里的每个人都是专家,他们知道 Rust 在 Linux 内核中是如何工作的。然而,Behme 不是计算机科学出身,他的背景是电子工程。
他展示了 /Linux 设备驱动程序/, 第三版 的图片,问道:是否也需要一本关于 Rust 内核抽象的书?人们都说 Rust 的学习曲线很陡峭 — 而且 Rust-for-Linux 更加陡峭,因为它涉及以特定风格编写底层代码,并且内核始终处于高强度开发中。
为了说明他的观点,Behme 展示了一些初学者关于编写内核 Rust 的问题的示例。一个人在编写模块时遇到了麻烦。Alice Ryhl 回复了他们,说他们正在使用的抽象改变了它的 API,并解释了如何调整他们的模块。这不是一个少见的问题 — 他说,其他人也报告说需要时间去适应。Behme 自己也花了一些时间来弄清楚设备树的抽象 — 大约花了一周。他说这不是抱怨,只是举例说明学习必要的先决条件可能很困难,以及项目可以拥有更好的学习材料。
Andreas Hindborg 说,当一个抽象进入内核树时,要求是必须有一个该抽象的使用者 — 所以代码树中应该有一个示例。他说,实际上,进入树中的抽象往往在文档中也包含很好的示例。因此,该项目无疑希望 Behme 要求的这类学习材料存在。
Miguel Ojeda 指出,可能会有关于 Linux 设备驱动程序的书籍,但 Rust 在内核中仍然处于起步阶段。他说,这些书籍的编写需要时间。“我们当时在考虑写一本书,”他继续说道,但现在工作量太大。
Behme 回复说,他确实认为该项目在文档方面做得很好,但还不够。在他工作的地方,他询问过他们是否可以很快开始使用 Rust-for-Linux;他的经理说不行,不是因为技术原因,而是因为社会性的原因 — 从 C 转到 Rust 的学习曲线对于他公司的大多数工程师来说太陡峭了。
一位听众询问,这种陡峭的学习曲线是由于语言本身造成的,还是由于 Rust-for-Linux 项目造成的。Behme 说,主要问题是 Rust,但该项目在其基础上又额外增加了复杂性。他举了查看一些 Rust 代码并发现它调用了 spin_lock()
的例子,但是“为什么没有 unlock”?(答案: spin_lock()
Rust 抽象返回一个保护对象,当该对象被丢弃时会自动释放锁 — 无论是程序员显式地丢弃,还是在函数结束时隐式地丢弃。)这些问题有示例,但底层的机制与 C 不同,这需要时间去学习。
Paul McKenney 指出,现代内核 C 代码实际上现在也有 类似的锁保护,也许这会让 Rust 使用锁保护对象不那么反直觉。Ryhl 很好奇,是否对不同语言之间常用的约定进行翻译会很有帮助。
Hindborg 同意学习一门语言需要时间,而且就命令式语言而言,Rust 确实很难学习。但是“你需要投入时间学习,它不是可以自然而然掌握的”。一旦你投入了时间,就会有很大的收益。他建议 Behme 告诉他的经理这一点,并指出 Google 声称使用 Rust 可以提高 3 倍的生产力。他还说,虽然 Rust-for-Linux 在普通 Rust 的基础上增加了一些额外的细节,但这对于内核来说并不是什么新鲜事 — 内核中的 C 与用户空间中的 C 相差很大。
Ryhl 询问,根据其他与会者的经验,教其他开发人员编写 Rust 需要什么。她指出,实际上,在 RustConf 上将有一个关于这个主题的演讲。另一位与会者指出,Rust-for-Linux 的补丁就像任何内核补丁一样,通过邮件列表进行处理 — 所以解释或说明更改的文档通常就在那里。Behme 询问是否可以为每个内核获得类似于发行说明的东西,谈论一下发生了什么变化。
Hindborg 回复说,所有更改都在 Git 中。Ojeda 建议,当 Behme 看到 API 的更改时,他应该去查看相应的提交。
Greg Kroah-Hartman 指出,内核的 C 开发人员没有提供内核内部更改信息 — 那么为什么 Rust 开发人员应该这样做呢?相关地,他建议不要使用 Linux 设备驱动程序,因为它现在已经严重过时了。Ojeda 同意,并指出 Behme 强调的所有更改都是针对内部 Rust API 的 — 就像其他内核接口一样,它们随时可能发生变化,这一点没有保证。
Richard Weinberger 认为 Behme 的观点很好 — 他指出,大多数编写设备驱动程序的人是电子工程师,而不是计算机科学家。从这个角度来看,Rust 看起来“离奇且充满敌意”。他说,如果你了解 OCaml 和 Haskell,Rust 看起来很棒。Rust-for-Linux 开发人员应该注意不要假设只了解 C 的内核黑客有相同的积极印象。
Hindborg 回复说,他理解 Weinberger 的观点,但他自己也是一名电子工程师,他先学习了 C,然后学习了 Rust。他说,这不是不可能的,你可以期望人们学习新工具。
“是的,但是你需要给他们学习的动力,”Weinberger 回复道。Benno Lossin 说,作为一名 Rust 文档编写者,他经常不知道初学者会理解什么。如果你从 Rust 的角度来看,代码中没有对应的 unlock()
的原因很清楚。他说,我们需要听取来自内核方面的人们的意见,他们遇到了问题,以便改进我们的文档。他要求 Behme 写下他遇到的问题,以便他们可以将其转化为一些文档。Behme 同意了。
Lossin 也同意,对 Rust API 的更改令人沮丧,但它们可以随着时间的推移变得更好 — 已经有一个预先的计划,将 kernel
crate 的一些功能拆分为更小的 crate,因此这些 crate 的更改频率应该更低。他说,现在有这么多人在开发 kernel
crate,以至于任何人都很难知晓所有更改。
Gary Guo 认为,Rust 实际上对于编写设备驱动程序的开发人员来说会大放异彩。他说,期望每位工程师都理解 C 的许多尖锐之处是不现实的。在 Rust 中,API 还没有完全到位,但有可能他们只需要编写安全的 Rust 代码。所以,让经验不足的工程师编写 Rust 实际上是有价值的 — 编译器会帮助他们编写更少的错误。
Simona Vetter 说,根据她的经验,普通内核 C 开发人员也不理解 C。理论上,有五个人可以有能力编写无错误的驱动程序,而实际上是没有人能做到。她说,编写无错误的内核代码实际上是不可能的。
Behme 回复说,在行业中,你必须编写驱动程序。因此,从真正的工程师那里获得可接受的驱动程序是必须的。Vetter 认为 Rust 实际上可以在这方面提供帮助 — 她的希望是,新工程师可以用 Rust 编写“随机代码”,并获得一个正确的驱动程序,这在 C 中永远不会发生。
Hindborg 认为这是一个有趣的观察。他预测,如果他们的雇主要求他们编写 Rust,很多人会很生气,因为没有人喜欢被编译器训斥。但尽管如此,当必要的库到位后,也许我们永远不会编译出有错误的驱动程序。
Ryhl 指出,她已经看到其他人为她的驱动程序做出了贡献的同时却没有添加任何抽象。所以至少在一个领域中,情况已经发展到大多数东西都很稳定的地步。
收集资源
此时,正式到了下一个会议的时间。但是,幸运的是,下一个会议计划是总结不同的教育材料,目的是为在内核中学习 Rust 生成推荐列表。
Ojeda 要求人们列出他们在学习 Rust 时发现最有帮助的资源。就他个人而言,他发现布朗大学 认知工程实验室 的 在线书籍 对他很有帮助,这本书有一个交互式借用(borrow)检查器。
Guo 开玩笑说,学习 Rust 的最好方法是学习 C++,讨厌它,然后学习 Rust。他说,很多概念都对应得上,但 Rust 好多了。Adrian Taylor 建议使用 New Rustacean 播客。他认为,用音频来学习一门编程语言很奇怪,但他很喜欢这种方式。他还建议了一系列文章,"以危险的方式学习 Rust",这篇文章展示了将 C 程序逐步转换为 Rust 的过程。
Kroah-Hartman 说,Linux 基金会有一个 免费在线课程 用于学习 Rust。Hindborg 说,谷歌也有一个免费的为期五天的课程,"全面的 Rust"。
Lossin 给出了一个更一般的建议 — 阅读博客。他说,有很多关于高级主题的好文章。他尤其喜欢 Amos Wenger 关于 Pin 的解释。Ojeda 建议使用 Aria Desires 的硕士论文 "你不能在 Trust 中拼写 Rust" 作为高级主题的良好资源。她还写了 "用太多链表学习 Rust",这本书当时没有人推荐,但它也是为有 C 语言经验的程序员提供的 Rust 入门书籍。
在收集了这些资源后,讨论转向了如何处理它们。Bilbao 说,该项目应该区分刚入门的人和在 Linux 中编写 Rust 有段时间的人 — 他们的需求不同。他建议使用 Rust-for-Linux 网站 作为托管好博客文章的中心位置,但也认为该项目必须“认真”地确保所有内容都有良好的文档。
Lossin 指出,已经有一个 linter 规则要求对所有公共项(函数和类型)进行文档化。他们简短地讨论了当前内核中为 C 代码编写文档的约定。
Vetter 最终指出了 kernel-doc
的一个问题, kernel-doc
是一个用于检查 C 代码是否已文档化的工具。当没有注释时,它不会抱怨,但如果有一个注释,而其他一些注释仍然缺失,它就会抱怨。这使得人们不想在还没有文档的地方添加文档。她说,Rust 领先一步,因为它只是要求文档存在,即使人们没有付出努力,也更容易在以后进行改进。她指出,善于编写复杂代码的人和善于编写文档的人之间往往没有很大的重叠 — 所以很适合鼓励人们合作。
总而言之,人们普遍认为,Rust-for-Linux 项目可以让人们更容易地掌握编写内核 Rust 所需的知识。因此,该项目将继续鼓励良好的文档标准,集中学习资源,并与其他内核开发人员合作,解决他们提出的痛点,找出还需要涵盖的内容。
[ 感谢 Linux 基金会,LWN 的旅行赞助商,为我们对 Kangrejos 的报道提供支持。 ]
全文完
LWN 文章遵循 CC BY-SA 4.0 许可协议。
欢迎分享、转载及基于现有协议再创作~
长按下面二维码关注,关注 LWN 深度文章以及开源社区的各种新近言论~