BTD-OS是一款基于 Rust 语言开发的宏内核操作系统,适用于 RISC-V64 平台。
它实现了中断与异常处理、进程管理、内存管理、文件系统和信号系统等操作系统基本模块。目前,BTD-OS 可以在 QEMU 虚拟环境和 HiFive Unmatched U740 板卡上运行。
BTD-OS 的核心目标是设计一款简洁、小巧、结构清晰、功能完善且具有良好可拓展性的操作系统。BiteTheDisk 团队在代码和文档中尽可能地保留了 BTD-OS 的设计与实现思路,包括问题与解决方案以及后续可能的优化方案,以展现操作系统的基本功能和核心思想,方便他人学习和借鉴,加深对操作系统基本原理与实现的理解。
编程语言的选择
虽然常见的操作系统内核都是基于 C 语言的,但 BTD-OS 使用 Rust 语言进行开发,原因如下:
- 内存安全性:Rust 是一种内存安全的编程语言,其借用检查器(Borrow Checker)可以在编译时捕获内存访问错误,避免了常见的内存安全问题,如空指针引用、数据竞争等。
- 性能:Rust 语言的设计目标之一是提供与 C 和 C++ 相媲美的性能。它具有零开销抽象、内联汇编和对底层硬件的直接访问等特性,使得开发人员能够编写高效的系统级代码。
- 可靠性:Rust 鼓励编写可靠的代码。其强制的所有权和借用规则以及丰富的静态类型系统可以在编译时捕获潜在的错误,减少运行时错误的可能性。
- 丰富的第三方库支持:Rust生态系统中有大量的高质量第三方库,可以帮助简化内核开发过程。
尽管C语言是广泛用于操作系统开发的传统语言,但 Rust 作为一种现代且创新的语言,为开发者提供了更好的工具和保证,有助于编写更安全、可靠和高效的操作系统代码。
开发历程
在比赛准备之前,我们的团队中的同学已经对 Rust 语言有初步的接触。恰好在学习 Rust 的过程中,我们发现了一个非常好的 Rust 入门项目,即 rCore-Tutorial-v3。于是我们参加了 rCore-Tutorial 的操作系统训练营。在开源社区的朋友们的帮助下,我们完成了部分实验,进一步加深了对操作系统基本原理以及 rCore 部分实现细节的理解。
在区域赛阶段,我们先简单阅读了部分往届优秀作品如 FTL-OS, NPUCore-OS, OopsOS, RongOS, JKXS-OS 等等。虽然这些优秀作品中,特别是获得了全国赛一等奖的作品,都有各自优秀的,独特的设计与优化方案,但这些设计与优化对于刚刚从 rCore-Tutorial 学习后的我们来说,理解起来比较吃力。于是在 BTD-OS 设计初期选择了与 rCore-Tutorail 设计比较贴合的 RongOS 作为参考模板,结合 rCore-Tutorial-v3 的 ch5 分支开发,尽可能地使内核看起来结构清晰,简洁小巧。
在全国赛第一阶段,主要工作是是移植 busybox 完善各个测试要求的系统调用以及接入硬件设备 HiFive Unmatched U740 板卡。在这个时期,我们花费了大量的时间根据 man-page 文档要求,完善初期要求实现的系统调用,添加新的系统调用,并在内核中加入这些系统调用要求维护的数据结构,参考往届作品中对硬件设备的移植方案等等。到第一阶段提交时,我们完成了大部分的测例,但仍有部分测例要求的结构与功能,如网络等,在内核中还未实现。另外,由于在线硬件资源较难获取,我们没有完成对于硬件接入的调试。同时,在QEMU平台上运行测试时,我们发现内核的执行速度非常慢,难以接受。于是在在全国赛第一阶段结束后,我们通过自己写的一些小的性能测试工具,如 time-tracer 发现了内核最大的性能问题 —— 大量地直接读写 FAT32 文件系统。
在进入全国赛第二阶段前,我们主要工作包括:通过引入 PageCache 机制,改进 FAT32 读写过程中的簇链查找模式以解决文件系统导致的性能问题;完善对硬件设备 HiFive Unmatched U740 板卡的支持;改进多核的支持;完成网络设计等工作。
完成情况
内核模块 | 完成情况 | 系统调用 |
---|---|---|
进程管理 | 分时多任务 多线程 多核 符合 man-page 规范的 futex 机制 |
clone, exec, wait4, exit, exit_group, getpid, getppid, gettid, set_tid_address, clock_gettime, kill, tkill, getscheduler clock_getres, socketpair, set_robust_list, get_robust_list, prlimit64 等 |
内存管理 | 页缓存 懒分配与写时拷贝 共享内存 |
brk, munmap, mmap, shmget, shmctl, shmat, shmdt, mprotect |
文件系统 | FAT32 块缓存 与内存页缓存结合 InodeCache |
getcwd, pipe2, dup, dup3, chdir, openat, close, getdents64, read, pread64, write, pwrite64, unlinkat, mkdirat, ummount2, mount, fstat, readv, writev, ioctl, fcntl, newfstatat, sendfile, utimensat, renameat2, lseek, readlinkat, sync, ftruncate64, pselect, statfs 等 |
信号系统 | 符合 man-page 规范的信号处理机制 | sigreturn, sigaction, sigprocmask |
其他系统调用 | times, uname, sched_yield, gettimeofday nanosleep, clock_nanosleep, gettrandom, settimer, getittimer, timer_settime, recvfrom |