Skip to content

同济大学操作系统课程小学期课设:基于Rust的多任务操作系统的设计和实现。仅供学习参考。An Operating System Designed and Implemented in Rust lang.

Notifications You must be signed in to change notification settings

Cinea4678/TJU-cinea-os

Repository files navigation

基于Rust语言的多任务操作系统的设计与实现

这是同济大学操作系统课程设计课程的暑期项目,从设计到完全实现总计用时三个月,总体代码一万余行。采用的语言是Rust语言,主要面向x86-64架构的计算机。本项目实现的操作系统具有现代操作系统的大部分功能和特性,并允许用户使用本项目中实现的工具集进行用户程序的开发。本项目实现的操作系统还提供了基础的图形界面(GUI)和多窗口支持。

这篇文章摘选自项目文档,你可以点击这里获取完整的项目文档(PDF 7.5MB 202页)

速览:本项目的特点

  • 使用现有、可靠的引导程序
  • 原生64位支持
  • 能够处理 PIC 8259 硬件中断
  • 支持 PS/2 键盘与鼠标
  • 支持串口通信
  • 页式内存管理
  • 链式堆内存分配
  • RTC 时钟支持
  • PCI 设备交互支持
  • ATA 硬盘读写支持
  • 基于 AHCI 协议的 SATA 硬盘读写支持
  • 支持伪随机数生成
  • FAT32 文件系统支持
  • 多进程管理和调度
  • 基于事件队列的事件等待和唤醒系统
  • 同时支持抢占式和非抢占式多任务,可以使用 async/await 运行多个协程。
  • 支持窗口显示、堆内存使用的用户空间,支持ELF可执行程序
  • 完全支持中文显示
  • 800 x 600 高清真彩图形显示
  • TTF 字体的读取和显示
  • BMP 图片的读取和显示
  • 简单的图形化 2048 游戏

项目开发环境

宿主机:MacBook Pro(2020 m1)和拯救者r9000p(2021)

虚拟机:QEMU v8.0.0 x86-64

开发软件:JetBreains CLion

语言:Rust(nightly-2023-06-19-x86_64-pc-windows-msvc)

项目设计

项目架构图

本项目主要由 3 个 Rust Crate 组成:系统内核系统接口用户程序

  • 系统内核部分:包含系统内核的入口点、初始化系统的程序,以及系统内核所需要的工具类,例如硬盘交互、中断处理。
  • 系统接口部分:包含被系统内核和用户程序共同需要的方法、类和常量,以及对系统调用的封装。例如,打开文件、读写文件的方法、表示时间的数据结构的封装。
  • 用户程序部分:包含数个即将被编译为可执行程序,在用户空间运行的程序。

为何不选用C语言?

长期以来, C语言是进行操作系统编程的经典选择。但是, C语言也有其劣势。首先,在内存管理上, C语言没有自动的内存管理机制,也就是说,程序员需要手动地分配和释放内存,这增加了编程的复杂度和出错的可能性。如果内存分配或释放不当,可能会导致内存泄漏、内存碎片、空指针、悬垂指针等问题,影响程序的性能和稳定性。

此外,在类型安全上, C语言对变量的类型检查不够严格,允许隐式的类型转换和指针运算,这可能会导致数据的损失或破坏。例如,C语言可以将一个浮点数赋值给一个整数,或者将一个指向字符的指针赋值给一个指向整数的指针,这些操作可能会造成精度的丢失或者内存的非法访问。

封装性上, C语言是一种面向过程的语言,它没有提供面向对象的特性,如类、继承、多态等。这使得C语言难以实现数据和代码的封装和抽象,也不利于程序的模块化和复用。C语言虽然可以通过结构体和函数指针来模拟一些面向对象的功能,但是这样做比较繁琐和低效。

使用外部库上, C语言缺乏官方的、权威的软件包管理机制,也缺乏统一的文档规则。这使得C语言很难快速找到合适的外部库及其文档;对外部库而言,每个库都需要开发者自行管理编译、链接和命名冲突,门槛相对较高。

异常处理上, C语言没有提供异常处理的机制,也就是说,当程序遇到错误或异常时,无法通过抛出或捕获异常来进行恢复或处理。 C语言只能通过返回错误码或使用全局变量来表示错误状态,这使得错误处理变得分散和混乱,也不利于程序的可读性和可维护性。

历程&感言

设计并撰写一个操作系统是大学期间一次独特而宝贵的经历。在学习操作系统开发的过程中,从选型到着手开发,实属不易。

最初看到于老师的《Orange’S》 一书,想要跟随学习,后发现难度过大,从GDT和TSS开始就几乎什么都跟不上了。最后只好放弃。之后也看过一段时间的《30天自制操作系统》,此书生动简单,作者著书时亦是一位和我年纪相差不大、爱好相似的“日本肥宅”,但无奈此书成书于二十年前,书中许多概念与工具早已过时, QEMU、 64位等更是不知何物。因此,一时间,何去何从竟难以抉择。

幸而,在互联网偶遇phil-opp(Philipp Oppermann)老师的《Writing an OS in Rust》系列博客,由于我那段时间特别偏爱Rust, 因此如同久旱逢甘,兴致冲冲地跟随其做了起来。作者实力不凡,不仅文章通俗易懂,更为初学者写好了大量工具,打通了阻碍初学者体验OS开发的几座高墙————引导程序、实模式、保护模式、长模式。在phil-opp老师的指引下,我顺利地度过了异常和中断处理、 VGA文本模式、内存和堆内存等几大难关。

然而,事情很难一帆风顺。 phil-opp老师在2020年后便不再更新《Writing an OS in Rust》系列博客,原因是他希望能用UEFI重写这个博客系列,因此他不得不放下这一版博客的更新。但是,他的博客最终仅仅止步“协程”部分。对进程这一巨大的难点,他仅仅留下“协程的非抢占式调度为我们之后进程的抢占式调度埋下基础”这样的一句话便再未更新。如何走完剩下的路,成了埋在我心头的一根刺,让我不时心烦意乱。

这时,我在《Writing an OS in Rust》 系列博客的评论区中偶然发现了一个指向vinc/moros项目的链接。这个项目继承《Writing an OS in Rust》而来,但是作者Vinc通读各大经典OS的源码,并在《Writing an OS in Rust》 的基础上实现了进程、 Shell等高级功能,将这个Rust系统变成了一个完整的的操作系统。我如获至宝,潜心研究moros, 并在moros的基础上完成了进程、进程切换、进入用户空间和系统调用。

但是,令人遗憾的是,moros并没有走出VGA的文本模式,可是我想做的系统是图形模式,可以画窗口、设背景,显示图片。因此,我第一次尝试跳出舒适圈,尝试自己探索教程、别人的代码里没有出现过的新技术。

图形模式就是我跳出舒适圈的“第一炮”。在翻阅《30天》时,我注意到作者说可以采用VESA协议来进入图形模式。因此,我开始尝试按照书上的方法调用VESA BIOS扩展(VBE)。可是,怎么实验也不成功。后来我才知道,这是因为调用VBE只能在实模式或V86模式中完成,但我已经进入长模式了。

正当棘手之际,我偶然间在一个叫做“OSDev Wiki”的网站上认识了一种叫做Bochs Graphics Adaptor的虚拟显卡,Bochs和QEMU两个经典虚拟机都支持它。通过这个虚拟显卡的接口,就可以直接在长模式中通过I/O就切换图形模式了。这是我第一次从OSDevWiki上获益,并且从此以后,我开始经常泡在上面查阅各种资料。这个网站上的文章内容详尽,却又不事无巨细、像官方说明书。它还会提供很多例程,对我的帮助很大。终于,经过日复一日的开发和成长,我已经可以不再参考别人的系统,而是根据自己的想法和见解随心所欲地实现我想要的功能。具体的例子就是我的操作系统的GUI窗口。我没有询问GPT什么是最佳实践,也没有看别人的代码。我自己构想和设计出了这个功能模块的架构,并成功地在代码中将它表达了出来。虽然它的性能不尽如人意,但是已经完全符合我的预期。

About

同济大学操作系统课程小学期课设:基于Rust的多任务操作系统的设计和实现。仅供学习参考。An Operating System Designed and Implemented in Rust lang.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages