#kernel #risc-v #scratch #language #platform #architecture #operating-systems

nightly app chyyuu/os

基于Rust/C语言和RISC-V 64/X86-32的OS内核实验室

1个不稳定版本

0.1.0 2020年4月8日

#338操作系统

3,923 星 & 222 关注者

140KB
4K SLoC

rCore-Tutorial-v3

rCore-Tutorial版本3.6。请参阅中文文档

rCore-Tutorial API文档。请参阅十个操作系统的API文档

如果您不了解Rust语言并想学习它,请访问Rust学习资源

官方QQ群号:735045051

新闻

  • 2022年6月23日:版本3.6.0正在路上!现在我们直接在chX分支上更新代码,请定期检查是否有更新。

概述

本项目旨在展示如何从零开始,使用Rust语言为初学者编写运行在RISC-V平台上的类似Unix的操作系统,无需任何关于计算机架构、汇编语言或操作系统的背景知识。

特点

  • 支持平台:qemu-system-riscv64 模拟器或基于Kendryte K210 SoC 的开发板,例如Maix Dock
  • 操作系统
    • 多个进程的并发,每个进程包含多个本地线程
    • 抢占式调度(轮询算法)
    • 内核中的动态内存管理
    • 虚拟内存
    • 一个带有块缓存的简单文件系统
    • 用户空间中的交互式shell
  • 代码行数只有4K+
  • 尽管代码中缺少注释,但提供了中文的详细文档(目前没有提供英文版本)

先决条件

安装Rust

查看官方指南

安装一些工具

$ rustup target add riscv64gc-unknown-none-elf
$ cargo install cargo-binutils --vers =0.3.3
$ rustup component add llvm-tools-preview
$ rustup component add rust-src

安装Qemu

在此,我们手动编译并安装Qemu 7.0.0。例如,在Ubuntu 18.04上

# install dependency packages
$ sudo apt install autoconf automake autotools-dev curl libmpc-dev libmpfr-dev libgmp-dev \
              gawk build-essential bison flex texinfo gperf libtool patchutils bc \
              zlib1g-dev libexpat-dev pkg-config  libglib2.0-dev libpixman-1-dev git tmux python3 python3-pip
# download Qemu source code
$ wget https://download.qemu.org/qemu-7.0.0.tar.xz
# extract to qemu-7.0.0/
$ tar xvJf qemu-7.0.0.tar.xz
$ cd qemu-7.0.0
# build
$ ./configure --target-list=riscv64-softmmu,riscv64-linux-user
$ make -j$(nproc)

然后,将以下内容添加到~/.bashrc中(请根据您的环境调整这些路径)

export PATH=$PATH:/home/shinbokuow/Downloads/built/qemu-7.0.0
export PATH=$PATH:/home/shinbokuow/Downloads/built/qemu-7.0.0/riscv64-softmmu
export PATH=$PATH:/home/shinbokuow/Downloads/built/qemu-7.0.0/riscv64-linux-user

最后,更新当前shell

$ source ~/.bashrc

现在我们可以检查Qemu的版本了

$ qemu-system-riscv64 --version
QEMU emulator version 7.0.0
Copyright (c) 2003-2020 Fabrice Bellard and the QEMU Project developers

安装RISC-V GNU嵌入式工具链(包括GDB)

根据您的平台,从Sifive网站下载压缩文件(使用Ctrl+F 'toolchain')。

解压并将其根目录下的'bin'目录的路径添加到$PATH

例如,我们可以检查GDB的版本

$ riscv64-unknown-elf-gdb --version
GNU gdb (SiFive GDB-Metal 10.1.0-2020.12.7) 10.1
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

安装串行工具(可选,如果您想在K210上运行的话)

$ pip3 install pyserial
$ sudo apt install python3-serial

运行我们的项目

Qemu

$ git clone https://github.com/rcore-os/rCore-Tutorial-v3.git
$ cd rCore-Tutorial-v3/os
$ make run

输出一些调试信息后,内核列出所有可用的应用程序并进入用户shell

/**** APPS ****
mpsc_sem
usertests
pipetest
forktest2
cat
initproc
race_adder_loop
threads_arg
race_adder_mutex_spin
race_adder_mutex_blocking
forktree
user_shell
huge_write
race_adder
race_adder_atomic
threads
stack_overflow
filetest_simple
forktest_simple
cmdline_args
run_pipe_test
forktest
matrix
exit
fantastic_text
sleep_simple
yield
hello_world
pipe_large_test
sleep
phil_din_mutex
**************/
Rust user shell
>> 

您可以运行除了initprocuser_shell自身以外的任何应用程序。要运行一个应用程序,只需输入其文件名并按回车键。推荐使用usertests,因为它可以运行多个应用程序。

输入Ctrl+a然后x来退出Qemu。

K210

在第六章之前,您不需要SD卡

$ git clone https://github.com/rcore-os/rCore-Tutorial-v3.git
$ cd rCore-Tutorial-v3/os
$ make run BOARD=k210

从第六章开始,在运行内核之前,我们应该将SD卡插入到PC中,并将文件系统镜像手动写入到SD卡

$ cd rCore-Tutorial-v3/os
$ make sdcard

默认情况下,它将覆盖设备/dev/sdb,即SD卡,但您可以提供另一个位置。例如,使用make sdcard SDCARD=/dev/sdc

之后,将SD卡从PC上拔出,并插入到K210的插槽中。将K210连接到PC,然后

$ git clone https://github.com/rcore-os/rCore-Tutorial-v3.git
$ cd rCore-Tutorial-v3/os
$ make run BOARD=k210

输入Ctrl+]来从K210断开连接。

显示操作系统内核版本的运行时调试信息

ch9-log分支包含大量调试信息。您可以尝试运行rcore教程以了解操作系统内核的内部行为。

$ git clone https://github.com/rcore-os/rCore-Tutorial-v3.git
$ cd rCore-Tutorial-v3/os
$ git checkout ch9-log
$ make run
......
[rustsbi] RustSBI version 0.2.0-alpha.10, adapting to RISC-V SBI v0.3
.______       __    __      _______.___________.  _______..______   __
|   _  \     |  |  |  |    /       |           | /       ||   _  \ |  |
|  |_)  |    |  |  |  |   |   (----`---|  |----`|   (----`|  |_)  ||  |
|      /     |  |  |  |    \   \       |  |      \   \    |   _  < |  |
|  |\  \----.|  `--'  |.----)   |      |  |  .----)   |   |  |_)  ||  |
| _| `._____| \______/ |_______/       |__|  |_______/    |______/ |__|

[rustsbi] Implementation: RustSBI-QEMU Version 0.0.2
[rustsbi-dtb] Hart count: cluster0 with 1 cores
[rustsbi] misa: RV64ACDFIMSU
[rustsbi] mideleg: ssoft, stimer, sext (0x222)
[rustsbi] medeleg: ima, ia, bkpt, la, sa, uecall, ipage, lpage, spage (0xb1ab)
[rustsbi] pmp0: 0x10000000 ..= 0x10001fff (rw-)
[rustsbi] pmp1: 0x2000000 ..= 0x200ffff (rw-)
[rustsbi] pmp2: 0xc000000 ..= 0xc3fffff (rw-)
[rustsbi] pmp3: 0x80000000 ..= 0x8fffffff (rwx)
[rustsbi] enter supervisor 0x80200000
[KERN] rust_main() begin
[KERN] clear_bss() begin
[KERN] clear_bss() end
[KERN] mm::init() begin
[KERN] mm::init_heap() begin
[KERN] mm::init_heap() end
[KERN] mm::init_frame_allocator() begin
[KERN] mm::frame_allocator::lazy_static!FRAME_ALLOCATOR begin
......

Rustdoc

目前它只能帮助您查看代码,因为只有一小部分代码被文档化。

您可以使用cargo doc --no-deps --openos目录下打开os的doc html。

OS-API-DOCS

Ten OS的API文档

  1. Lib-OS API文档
  2. Batch-OS API文档
  3. MultiProg-OS API文档
  4. TimeSharing-OS API文档
  5. AddrSpace-OS API文档
  6. Process-OS API文档
  7. FileSystem-OS API文档
  8. IPC-OS API文档
  9. SyncMutex-OS API文档
  10. IODevice-OS API文档

进行中

我们的第一个版本3.6.0(第1-9章)已经发布,我们仍在继续完善它。

  • 第9章:需要更多关于不同I/O设备的描述

以下是自3.5.0以来的更新

完成

  • 在运行项目到不同平台之前,自动清理并重新构建
  • 修复了早期章节中的power系列应用程序,现在可以在输出中找到模数
  • 使用 UPSafeCell 替代 RefCellspin::Mutex 来访问静态数据结构,并调整其 API 以防止同时借用两次(在 run_first_task 中提及 & .exclusive_access().task[0]
  • TaskContext 移入 TaskControlBlock,而不是在内核堆栈上原地恢复(自第3章起),消除令人烦恼的 task_cx_ptr2
  • asm! 替换 llvm_asm!
  • rcore-fs-fuse 生成的 fs 图像大小扩展到 128MiB
  • 添加一个名为 huge_write 的新测试,该测试评估 fs 性能(qemu 约 500KiB/s,k210 约 50KiB/s)
  • 在涉及写操作的 fs 事务后,将所有块缓存刷新到磁盘
  • 在 SMP 章节之前用 UPSafeCell 替换 spin::Mutex
  • 添加关于同步与互斥的新章节代码(仅限单处理器)
  • 错误修复:在 PageTable::unmap 中应调用 find_pte 而不是 find_pte_create
  • 澄清:“在 find_pte 中检查第三级 pte 的有效性,而不是在此函数外部检查” 不应是一个错误
  • 第8章的代码:单处理器的同步
  • 交换第6章和第7章的代码
  • 在第7/8章支持信号机制(仅适用于单线程的应用程序)
  • 添加 boards/ 目录并支持 rustdoc,例如,您可以使用 cargo doc --no-deps --open 来查看 crate 的文档
  • 第9章的代码:基于中断的设备驱动程序,包括 UART、块、键盘、鼠标、GPU 设备
  • 在 GitHub 中添加 CI 自动测试和文档

待办事项(高优先级)

  • 审查文档,当前进度:8/9
  • 可选地使用旧的 fs 图像,而不总是重建图像
  • shell 功能改进(待续...)
  • 为每个非零进程退出代码提供一个唯一且清晰的错误类型
  • 有效处理 mm 模块的错误
  • 添加更多 os 函数以理解 os 概念和原则

待办事项(低优先级)

  • 重写实践文档并删除一些不适当的问题
  • 在 Rust 源代码级别提供流畅的调试体验
  • 使用官方工具格式化代码

Crates

我们将在以后添加它们。

依赖项

~5MB
~66K SLoC