使用Rust在树莓派上编写操作系统 - 项目介绍
ℹ️ 介绍
这是一个教程系列,面向那些不熟悉ARM 64 bit ARMv8-A架构的操作系统开发爱好者。这些教程将逐步指导如何从头开始为嵌入式系统编写宏内核。教程涵盖了常见操作系统功能的实现,例如向串口写数据、设置虚拟内存和处理硬件异常。同时,利用Rust特有的语言特性来提供内存安全性和执行速度。
祝读者们看得开心!
Andre (@andre-richter)
P.S.:中文🇨🇳译版的教程由@colachg和@readlnh发起。您可以在相应的文件夹中以README.CN.md
的形式找到这些翻译。当然,翻译会一定程度上落后原文的进度。
📑 组织
- 教程的每一章都包含一个独立可引导的二进制内核文件。
- 每一篇新的教程都建立在前一篇的基础上。
- 每一篇教程的
README
文件都会有一个简短的tl;dr
小节,用于简要概述本章的新内容,并展示与前一篇教程源代码的diff
,以方便读者检查修改和新增的代码。- 除了
tl;dr
小节之外,一些教程还配有完整、详尽的文本说明。这个系列教程的长期计划是为教程的所有章节都编写详细说明,不过目前我仅为我认为tl;dr
和diff
不足以解释清楚的教程章节编写详细说明。
- 除了
- 这些教程中的代码支持在树莓派3和树莓派4上运行。
- 教程的第1章到第5章是基础代码,仅用于在
QEMU
中运行。 - 从教程的第5章开始,您就可以在真正的树莓派上加载运行内核,并通过
UART
观察输出。
- 教程的第1章到第5章是基础代码,仅用于在
- 尽管教程将树莓派3和4作为为目标开发板,但文章中的代码均以模块化方式编写,可以轻松移植到其他CPU架构或开发板上。
- 如果真的有朋友尝试为
RISC-V
指令集编写实现我将非常高兴!
- 如果真的有朋友尝试为
- 代码编辑器的选择,我推荐安装Rust Analyzer插件的Visual Studio Code。
- 除了阅读教程每一章的文本之外,还可以使用
cargo
的make doc
命令,以方便的查看源码中丰富的文档和注释。
make doc
的输出
🛠 系统要求
本教程主要针对基于Linux的发行版。大部分代码同样适用于一些Unix版本,例如macOS,但这只是实验性的。
🚀 tl;dr 版本
确保你的用户帐户在docker group中。
准备
Rust
工具链。第一次使用rust-toolchain就能够自动搞定大部分工具。而需要我们手动操作的是:- 如果你已经安装了Rust:
1
cargo install cargo-binutils rustfilt
- 如果你需要从头安装Rust:
1
2
3
4curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source $HOME/.cargo/env
cargo install cargo-binutils rustfilt如果您使用
Visual Studio Code
,我们强烈建议你使用Rust Analyzer插件。如果你不使用Linux,则还需要安装一些
Ruby
gems:1
2
3sudo gem install bundler
bundle config set path '.vendor/bundle'
bundle install
🧰 更多细节:消除工具链麻烦
本系列试图将重点放在用户友好性上。因此,已尽可能消除嵌入式开发中最大的痛点:工具链麻烦
。
Rust本身已经在这方面提供了很大帮助,因为它内置了对交叉编译的支持。我们从x86
主机交叉编译到树莓派的AArch64
架构所需的一切都将由rustup
自动安装。但是,除了Rust编译器之外,我们还将使用更多工具。其中:
QEMU
:用于在编程机上模拟目标机的内核。Minipush
:我们自制的小工具,可通过UART
按需将内核加载到树莓派上。OpenOCD
和GDB
:用于在目标机上进行调试。
在编程主机上安装、编译每个工具的正确版本时,可能会出错很多。例如,编程机的发行版可能不提供所需的最新版本。或者在编译这些工具之一时缺少一些难以获得的依赖项。
这就是为什么我们会尽可能使用Docker。我们提供了一个附带的容器,其中预装了所有需要的工具或依赖项,一旦有需要docker就会自动pull下来。如果您想了解有关Docker的更多信息,并查看我们提供的容器,请查看docker文件夹。
📟 USB 串行输出
由于教程中开发的内核在真实硬件上运行,因此强烈建议您购买USB转串口线缆以获得完整体验。
- 你可以购买诸如[1] [2]的USB转串口线缆,当然还有许多其他类似的线缆。总的来说,你的线缆最好基于
CP2102
芯片。 - 将线缆连接到树莓派的
GND
和GPIO14/15
引脚,如下所示。 - 第5章是第一个用到它的地方。查看有关如何准备SD卡以从中引导自制内核的说明。
- 从第6章开始,在树莓派上启动内核就会变得很很舒服。本教程开发了一个名为
chainloader
的程序,用于在最后手动将内核拷贝到树莓派上,并将使你能够在启动期间通过UART
按需加载教程内核。
🙌 致谢
教程的原始版本最初是基于Zoltan Baldaszti用C
编写的[RPi3上的裸机编程教程](https://github.com/bztsrc/ raspi3-tutorial。谢谢你给了我们一个良好的开始!
许可
以下两种许可均可:
- Apache 许可证,版本 2.0,(LICENSE-APACHE 或 http://www.apache.org/licenses/LICENSE-2.0)
- MIT 许可证 (LICENSE-MIT 或 http://opensource.org/licenses/MIT)
参与本项目
您的提交将如Apache-2.0许可定义的那样,会纳入上述两个许可,且不包含任何附加条款。