定稿
量子思维队 authored
387d8935

Quantum_Mind_OS

所属学校:华东师范大学

比赛方向:小型内核实现

队伍名称:量子思维队

队伍ID:T202410269994316

指导老师:石亮

队员:朱昭荣、傅艺洋

详细文档可参考QM-os内核设计手册

简介

QM-OS 是一个基于 RISC-V 架构设计的多核宏内核模块化操作系统,全面复现了 UNIX v6 的核心功能,同时针对现代操作系统设计进行了性能优化与扩展。系统实现了文件系统、进程管理、内存管理、中断处理、设备驱动等核心模块,支持多核调度和虚拟内存管理。QM-OS 提供了丰富的高级功能,同时注重代码的模块化设计,具备良好的可扩展性和性能。

以下为QM-OS系统的系统结构概览图

系统架构图\

详细架构如下:

QM-OS
├── include头文件仓库
├── kernel
│   ├── boot
│   │   ├── main.c             内核入口函数
│   │   ├── start.c            启动模块
│   │   ├── entry.S            加载启动函数
│   │   └── Makefile
│   ├── dev
│   │   ├── virtio.c           virtio 驱动实现
│   │   ├── uart.c             串口中断处理
│   │   ├── timer.c            时钟中断管理
│   │   ├── plic.c             PLIC 中断控制
│   │   ├── console.c          控制台抽象支持
│   │   └── Makefile
│   ├── lib
│   │   ├── print.c            打印和调试功能
│   │   ├── spinlock.c         自旋锁实现
│   │   ├── sleeplock.c        睡眠锁支持
│   │   ├── str.c              字符串操作函数
│   │   └── Makefile
│   ├── proc
│   │   ├── cpu.c              CPU 管理模块
│   │   ├── proc.c             进程管理模块
│   │   ├── exec.c             ELF 程序执行模块
│   │   ├── swtch.S            上下文切换模块
│   │   └── Makefile
│   ├── mem
│   │   ├── pmem.c             物理内存管理
│   │   ├── kvm.c              内核虚拟内存管理
│   │   ├── uvm.c              用户虚拟内存管理
│   │   ├── mmap.c             内存映射功能支持
│   │   └── Makefile
│   ├── fs
│   │   ├── buf.c              缓存块操作
│   │   ├── fs.c               文件系统实现
│   │   ├── bitmap.c           位图操作模块
│   │   ├── inode.c            索引节点操作
│   │   ├── dir.c              目录操作支持
│   │   ├── file.c             文件操作实现
│   │   └── Makefile
│   ├── syscall
│   │   ├── syscall.c          系统调用处理
│   │   ├── sysfile.c          文件相关系统调用
│   │   ├── sysproc.c          进程相关系统调用
│   │   └── Makefile
│   ├── trap
│   │   ├── trap_kernel.c      核心态的中断处理
│   │   ├── trap_user.c        用户态中断处理
│   │   ├── trap.S             中断处理逻辑
│   │   ├── trampoline.S       上下文切换相关的工作
│   │   └── Makefile
│   ├── Makefile
│   └── kernel.ld              链接脚本
├── mkfs
│   ├── mkfs.c                 文件系统初始化工具
│   └── Makefile
├── user
│   ├── syscall_arch.h         系统调用的架构支持
│   ├── syscall_num.h          系统调用编号
│   ├── sys.h                  用户态系统调用接口
│   ├── type.h                 类型定义
│   ├── userlib.h              用户态库支持
│   ├── initcode.c             初始化代码
│   ├── test.c                 测试代码
│   ├── user_lib.c             用户态库实现
│   ├── user_syscall.c         用户态系统调用实现
│   ├── user.ld                用户态链接脚本
│   └── Makefile
├── Makefile                   顶层构建文件
└── common.mk                  公共构建文件

环境与依赖(Environment and Dependencies)

本操作系统需要在 RISC-V 架构的模拟环境下运行,推荐的工具和环境如下:

  • 操作系统与基础工具链: 在 Linux 环境(如 Ubuntu 18.04+)下进行实验,确保安装 GNU Make、Git等基本工具。 使用 git 便于版本管理和代码回退;

  • RISC-V 工具链: 需要安装 riscv64-unknown-elf-gccriscv64-unknown-elf-ldriscv64-unknown-elf-gdb 等交叉编译和调试工具。这些工具可从官方 RISC-V 工具链仓库或相应的包管理器安装,用于将 C 代码编译为 RISC-V 架构指令并对其进行调试。 检查工具链是否安装成功的方法:

    riscv64-unknown-elf-gcc --version
    qemu-system-riscv64 --version
  • QEMU 虚拟机: 使用 QEMU 来模拟 RISC-V 虚拟硬件平台,并在其中运行编译后的内核镜像。QEMU 可从官方仓库或包管理器安装。 启动内核测试示例。QM-OS系统的构建和运行相关参数写在 Makefile 中:

    make qemu
  • 类 xv6 操作系统: 本操作系统参考mit的基于riscv的xv6系统。

  • 无额外标准库依赖: 内核中使用的函数通常是由内核自行提供的简化版本,不需外部C标准库支持。

通过上述环境与工具的配置,可在模拟环境下对内核进行编译、运行和调试。若出现问题,可使用 GDB 远程调试功能、printf 调试以及在用户态增加测试代码来定位与解决问题。

完成情况

目前已经完成了boot模块,中断处理模块,内存管理模块,进程调度模块,文件系统模块这些操作系统所必备的模块和功能。

模块 完成情况与功能描述
文件系统 实现了类似 Linux 下 ext2 文件系统,支持文件的创建、删除、读写等操作。通过磁盘上记录文件块身份与空闲块情况,结合 LRU 算法优化磁盘缓存,提高文件访问效率。
进程管理 支持多核调度,实现了时间片轮转调度(Round Robin Scheduling)。通过 fork 系统调用创建进程,支持进程的上下文切换与独立页表。
内存管理 包括物理内存管理(基于空闲页链表管理,支持页级分配和回收)、虚拟内存管理(支持 RISC-V Sv39 三级页表结构,内核与用户地址空间分离)、分页机制及 mmap 支持。同时实现了 Copy-On-Write(COW),显著优化了 fork 系统调用的性能,减少不必要的物理页复制。
中断处理 支持 RISC-V 平台 PLIC 的中断控制,包括时钟中断、UART 中断等,完成了基础的中断处理与调度机制。
设备驱动 实现了控制台设备(console)的抽象与支持,为用户态程序提供 I/O 接口。

QM-OS 不仅实现了操作系统所必备的基础功能,还扩展了多个系统调用,提供了完整可靠的用户态支持

系统调用                      		  描述
-------------------------------------------------------------------------------------
int fork()                    		创建一个新进程,返回子进程的 PID。
int exit(int status)          		结束当前进程;退出状态通过 wait() 返回。不返回值。
int wait(uint64 *status)      		等待子进程退出;退出状态存储在 *status 中;返回子进程 PID。
int kill(int pid)             		终止指定 PID 的进程。成功返回 0,失败返回 -1。
int getpid()                  		返回当前进程的 PID。
int sleep(uint32 seconds)     		进程暂停指定的秒数。
int exec(char *file, char *argv[])	加载文件并执行,支持传递参数;仅在出错时返回。
char *sbrk(uint64 n)          		增长进程堆空间 n 字节。返回新堆空间起始地址。
int open(char *file, int flags)		打开文件;flags 表示读写模式;返回文件描述符。
int read(int fd, char *buf, int n)	从文件描述符 fd 读取 n 字节到缓冲区 buf 中;返回读取字节数。
int write(int fd, char *buf, int n)	将缓冲区 buf 中的 n 字节写入文件描述符 fd;返回写入字节数。
int close(int fd)             		关闭文件描述符 fd。
int dup(int fd)               		复制文件描述符 fd,返回新文件描述符。
int mkdir(char *dir)          		创建新目录。
int chdir(char *dir)          		改变当前工作目录。
int link(char *file1, char *file2)	为 file1 创建另一个文件名 file2。
int unlink(char *file)        		删除文件。
int fstat(int fd, uint64 addr)		获取文件描述符 fd 的信息并存入 addr 指定的内存中。
int mmap(uint64 start, uint32 len)	将长度为 len 字节的内存映射到 start 地址。
int munmap(uint64 start,uint32 len)	解除从 start 地址开始的长度为 len 字节的内存映射。
int brk(uint64 new_heap_top)  		设置或获取堆顶地址;支持堆空间增长或收缩。
int ps()                      		返回当前进程的 PID。
int psp()                     		返回当前进程父进程的 PID。
int time()                    		返回当前系统时间(以时钟滴答数为单位)。
int getcwd()                  		输出当前工作目录路径。

开发过程

截至12月24日,该系统总共经历了90余次修改(以commit次数计算)。可以参考我们的commit记录

由linux中eloc统计,代码总行数约6k行,功能实现丰富,检查全面,健壮性强。已经经过大量的测试用例,证明了代码的正确。

阶段性介绍可在各个版本的readme中查看

版本号 完成内容 分支链接
Version 0.1 完成机器启动模块并实现所需库 gitlab
Version 0.2 完成内存管理模块,实现虚拟内存 gitlab
Version 0.3 完成中断处理模块 gitlab
Version 0.4 完成进程结构的设计 gitlab
Version 0.5 完成进程调度模块 gitlab
Version 0.6 完成进程管理模块 gitlab
Version 0.7 初始文件系统模块 gitlab
Version 0.8 完成文件系统上层抽象、实现系统调用 gitlab
Version 0.9 文件系统完善、增加系统调用 gitlab
master 添加解释文档 gitlab

创新点

我们实现的创新点包括但不限于:

  1. 扩展文件系统(ext2)支持
    实现类似 ext2 的多级索引文件系统,支持高效的文件创建、删除、读写及目录管理;引入 LRU 缓存算法 优化磁盘 I/O 性能,动态维护缓存块状态,显著提升文件系统响应速度。

  2. 内存管理优化
    实现 写时复制(Copy-On-Write, COW)延迟分配(Lazy Allocation) 技术,大幅提升内存利用率,减少资源浪费;完整支持分页机制(每进程独立页表)、虚拟地址空间隔离及 mmap 内存映射功能,优化栈与堆的动态管理。

  3. 多核调度与时间片轮转(Round Robin)算法优化
    支持双核架构,采用高效的 时间片轮转调度算法 实现多进程管理与多核并行调度,提升系统资源利用率和响应速度。

  4. 模块化宏内核架构
    内核模块化设计,将机器启动、内存管理、中断处理、进程调度、文件系统和设备驱动分为独立模块,通过明确接口减少耦合,提升代码复用性与扩展性。

  5. 全面的系统调用支持
    实现 24 个核心系统调用,包括文件操作(如 open, read, write)、内存管理(如 brk, mmap)及进程管理(如 fork, exec, wait);为用户程序提供了丰富的接口支持,并显著优化了系统调用执行效率。

未来预期实现新功能

  • 高响应比优先(HRRN)算法
  • 实现 UNIX 下的管道机制
  • 内核线程支持
  • 实现更多系统调用
  • 伙伴系统和 slab 分配器

参考工作