rCore基础测验概览
Rust 语言进阶 & OS 入门** 的配套实验仓库 oscamp-base-experiment。
这一阶段的定位是帮助学员在正式编写 rCore 操作系统内核前,补齐系统级编程经验和操作系统底层的设计思想。整个项目共有 6个模块(Modules),包含 23 个渐进式的底层练习题,通过类似 rustlings 的命令行工具 oscamp 配合 todo!() 填空的形式进行自学与测试。
下面是每个章节(Module)及各个具体实验(Exercise)在教你做什么的详细解析:
Module 1: Concurrency (Synchronous) — 同步并发编程
核心目的:让你掌握 Rust 标准库下的基础多线程并发、共享状态管理、通道通信以及进程管道交互。
01_thread_spawn(线程创建)- 教你做:如何使用
thread::spawn创建新线程,理解 Rust 中的闭包捕获机制(特别是move关键字进行所有权转移),以及如何使用join()等待子线程结束。
- 教你做:如何使用
02_mutex_counter(互斥锁计数器)- 教你做:如何结合引用计数智能指针
Arc<T>与互斥锁Mutex<T>(即Arc<Mutex<T>>)实现多线程安全地共享并修改同一个计数器。
- 教你做:如何结合引用计数智能指针
03_channel(消息通道)- 教你做:掌握 Rust 标准库的
mpsc::channel(多生产者单消费者),学习如何在线程间安全地发送和接收消息,体会线程间的解耦。
- 教你做:掌握 Rust 标准库的
04_process_pipe(进程管道)- 教你做:在 Rust 中使用
Command运行外部子进程,并通过Stdio::piped()捕获其标准输出/输入,实现进程级别的管道重定向与交互。
- 教你做:在 Rust 中使用
Module 2: no_std Development — 裸机(无标准库)开发
核心目的:脱离标准库的保护,学习如何在“零操作系统的裸机环境”下直接管理内存、封装底层系统调用,这是编写 OS 内核的基石。
01_mem_primitives(内存基本操作)- 教你做:在不依赖标准库(
no_std)的情况下,自己动手用 Rust 实现 C 标准库最基础的内存与字符串操作函数,如memcpy、memset、memmove、strlen、strcmp。
- 教你做:在不依赖标准库(
02_bump_allocator(Bump 内存分配器)- 教你做:学习实现一个超简单的单向递增(Bump)分配器,为其实现 Rust 内核堆分配所需的
GlobalAlloctrait,并使用基于 CAS (Compare-And-Swap) 的无锁机制确保其线程安全。
- 教你做:学习实现一个超简单的单向递增(Bump)分配器,为其实现 Rust 内核堆分配所需的
03_free_list_allocator(空闲链表内存分配器)- 教你做:实现一个更实用的空闲链表分配器,掌握如何编写侵入式双向链表,并实现
First-Fit(最先匹配)分配策略。
- 教你做:实现一个更实用的空闲链表分配器,掌握如何编写侵入式双向链表,并实现
04_syscall_wrapper(系统调用封装)- 教你做:学习如何通过 Rust 内联汇编(
asm!)在不同的硬件架构(x86_64、aarch64、riscv64)上直接封装并触发底层的系统调用。
- 教你做:学习如何通过 Rust 内联汇编(
05_fd_table(文件描述符表)- 教你做:实现一个文件描述符表(File Descriptor Table),学习通过动态分发
Arc<dyn File>统一管理不同的打开文件,以及空闲文件描述符的复用和回收策略。
- 教你做:实现一个文件描述符表(File Descriptor Table),学习通过动态分发
Module 3: OS Concurrency Advanced — 操作系统并发进阶
核心目的:跳过标准库现成的锁,深入更底层的原子操作和硬件同步机制,在硬件级上自己实现锁和并发同步原语。
01_atomic_counter(原子计数器)- 教你做:使用 Rust 的原子类型(如
AtomicU64),掌握原子加法fetch_add以及基于 CAS 循环自旋的无锁并发原理。
- 教你做:使用 Rust 的原子类型(如
02_atomic_ordering(内存屏障与内存顺序)- 教你做:理解复杂的内存顺序(Memory Ordering,如 Release-Acquire 释放-获取语义),以及如何使用原子变量无锁实现一个线程安全的
OnceCell。
- 教你做:理解复杂的内存顺序(Memory Ordering,如 Release-Acquire 释放-获取语义),以及如何使用原子变量无锁实现一个线程安全的
03_spinlock(自旋锁)- 教你做:利用原子变量的
compare_exchange和硬件支持的spin_loop暂停指令,在裸机上从头实现一个自旋锁(Spinlock)。
- 教你做:利用原子变量的
04_spinlock_guard(RAII 锁守卫)- 教你做:为自旋锁实现 RAII(资源获取即初始化)守卫
SpinlockGuard,通过实现 Rust 的Deref、DerefMut和Droptrait,使得锁可以在离开作用域时自动释放,防止死锁。
- 教你做:为自旋锁实现 RAII(资源获取即初始化)守卫
05_rwlock(读写锁)- 教你做:在不依赖
std::sync::RwLock的前提下,手写一个支持写者优先(Writer-Priority)的读写锁,处理多读单写的同步场景。
- 教你做:在不依赖
Module 4: Context Switching — 上下文切换
核心目的:这是理解进程/线程调度的核心!通过保存与恢复 CPU 寄存器,实现最底层的控制流切换。该模块专为 riscv64 架构设计。
01_stack_coroutine(有栈协程)- 教你做:学习 RISC-V 架构下的被调用者保存寄存器(Callee-saved registers)和栈帧布局,手写汇编指令实现最核心的控制流跳转和上下文切换(Context Switch)。
02_green_threads(绿色线程调度器)- 教你做:在上下文切换的基础上构建一个绿色线程调度运行时,实现协作式线程调度(Cooperative Scheduling)及主动让出 CPU(
yield)的机制。
- 教你做:在上下文切换的基础上构建一个绿色线程调度运行时,实现协作式线程调度(Cooperative Scheduling)及主动让出 CPU(
Module 5: Async Programming — 异步编程
核心目的:深入 Rust 的协程与异步机制。不只学会用 async/await,更要明白底层的异步运行时(Runtime)是如何调用协程的。
01_basic_future(手写 Future)- 教你做:脱离
async关键字,手动实现 Rust 核心库的Futuretrait,编写底层的Poll状态返回逻辑,并掌握如何管理和唤醒Waker。
- 教你做:脱离
02_tokio_tasks(Tokio 异步任务)- 教你做:学习在真实的
Tokio异步运行时下,使用tokio::spawn产生并发执行的异步任务,并合理管理JoinHandle。
- 教你做:学习在真实的
03_async_channel(异步通道)- 教你做:利用
tokio::sync::mpsc实现非阻塞的、支持异步等待的生产者-消费者模式消息通道。
- 教你做:利用
04_select_timeout(Select 与超时控制)- 教你做:学习使用
tokio::select!宏进行多路异步任务并发竞争,实现超时控制、任务取消以及多任务竞态执行的处理。
- 教你做:学习使用
Module 6: Page Tables — 页表管理
核心目的:理解虚拟内存与地址空间,这是操作系统提供内存安全隔离的最重要硬件机制。
01_pte_flags(页表项标志位操作)- 教你做:理解 RISC-V SV39 分页方案下的页表项(PTE)位布局,通过位运算来构造、修改和解析 PTE 的各种控制标志位(如 R/W/X 权限和有效位 V)。
02_page_table_walk(单级页表与地址翻译)- 教你做:学习单级页表下的虚拟地址到物理地址的映射机制。练习如何解析虚拟页号(VPN),手动模拟地址转换过程,并能识别和触发缺页异常(Page Fault)。
03_multi_level_pt(SV39 多级页表映射)- 教你做:实现 SV39 三级页表的手动遍历(Page Table Walk)。在缺页时能够动态创建下级页表,建立或拆除虚实地址映射关系,并支持 2MB 大页(Huge Pages)的映射。
04_tlb_sim(TLB 模拟器)- 教你做:模拟实现内存管理单元(MMU)中的快表(TLB)。自己编写 TLB 的查询、插入、FIFO(先进先出)页面替换算法,并实现清理(Flush)全部或特定页/特定地址空间(ASID)快表项的逻辑。