# 操作系统实践 **Repository Path**: raitocc/riscv-os ## Basic Information - **Project Name**: 操作系统实践 - **Description**: 操作系统实践课程设计 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-09-16 - **Last Updated**: 2025-12-24 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # RISC-V OS (Course Project) ![RISC-V](https://img.shields.io/badge/Architecture-RISC--V-black) ![OS](https://img.shields.io/badge/Type-Operating%20System-blue) ![Status](https://img.shields.io/badge/Status-Completed-success) 这是一个从零构建的基于 RISC-V 架构的教学操作系统。本项目作为操作系统课程设计成果,参考了 xv6-riscv 的设计理念,实现了从裸机启动到用户态 shell 的完整功能链条。 **当前状态**:已完成所有基础实验(Exp 0-7)及扩展项目(ELF 加载器)。 ## 功能特性 (Features) 本项目涵盖了操作系统核心组件的完整实现: * **基础架构**: * [x] **Exp 0 & 1**: 环境搭建 & RISC-V 裸机启动 (Bootloader)。 * [x] **Exp 2**: 实现了内核级 `printf` 格式化输出及 UART 驱动。 * **内存管理**: * [x] **Exp 3**: 物理内存分配器 (kalloc) 与 Sv39 多级页表管理 (Virtual Memory)。 * **中断与异常**: * [x] **Exp 4**: 完整的 Trap 处理机制,支持时钟中断与上下文保存/恢复。 * **进程管理**: * [x] **Exp 5**: 进程控制块 (PCB)、进程状态机、简单的轮转调度算法 (Round Robin)。 * **系统调用**: * [x] **Exp 6**: 实现了标准系统调用接口 (fork, exec, wait, write, etc.),支持用户态与内核态交互。 * **文件系统**: * [x] **Exp 7**: 实现了基于 inode 的简易文件系统,支持日志 (Logging) 以保证崩溃一致性。 * **扩展功能**: * [x] **Exp 8 (Project 2)**: **ELF 加载器**。 * 实现了标准 ELF 可执行文件格式的解析。 * 支持将用户程序加载到独立的虚拟地址空间执行。 * 完善了 `exec` 系统调用,使 OS 能够运行编译后的标准 C 程序。 ## 开发环境 (Environment) 本项目在 **Ubuntu 22.04/24.04 LTS** 境下进行部署。 **核心依赖工具:** * **Compiler**: `riscv64-unknown-elf-gcc` * **Emulator**: `qemu-system-riscv64` * **Debugger**: `gdb-multiarch` * **Build**: `make` ## 快速开始 (Quick Start) ### 1. 编译并运行 使用默认的 `Makefile` 即可一键编译内核及用户程序,并启动 QEMU: ```bash # 编译内核与用户程序,并启动 QEMU make qemu ``` 启动成功后,你将看到类似以下的输出,并进入 Shell: ```text init: starting shell Welcome to My Tiny Shell! $ ``` ### 2. 调试模式 如果需要使用 GDB 进行调试: **终端 A (启动 QEMU GDB Server):** ```bash make qemu-gdb ``` **终端 B (连接 GDB):** ```bash gdb-multiarch kernel/kernel.elf ``` **或使用 IDE 的远程调试功能** ### 3. 测试 项目中包含了一些用户态测试程序(如 `usertest`),可以在 Shell 中直接运行: ```bash $ pipetest Parent: reading from pipe... Child: writing 'Hello' to pipe... Parent: received 12 bytes: 'Hello World' ``` ## 目录结构 (Project Structure) 符合课程要求的标准目录结构设计: ```text riscv-os/ ├── kernel/ # 操作系统内核源码 │ ├── boot/ # 启动代码 (entry.S, start.c) │ ├── fs/ # 文件系统实现 (fs.c, log.c, bio.c) │ ├── mm/ # 内存管理 (kalloc.c, vm.c) │ ├── proc/ # 进程管理 (proc.c, exec.c, trap.c) │ └── ... ├── user/ # 用户态程序与库 │ ├── ulib/ # 用户库 (ulib.c, user.h) │ ├── src/ # 用户程序 (shell.c, init.c, ls.c) ├── include/ # 内核头文件 (kernel shared headers) ├── mkfs.c # 文件系统镜像制作工具 ├── Makefile # 项目构建脚本 └── README.md # 本文件 ``` ## 扩展项目说明:ELF 加载器 **主要工作内容:** 1. **ELF 解析**:在 `kernel/proc/exec.c` 中实现了对 ELF Header 和 Program Header 的解析逻辑,能够识别 `ELF_MAGIC` 并读取段信息。 2. **内存映射**:根据 ELF 程序头表(Program Header Table),将代码段(Text)和数据段(Data)加载到用户进程的虚拟地址空间,并正确设置权限(R/W/X)。 3. **栈构建**:为用户进程分配并初始化用户栈,支持参数传递(argc, argv)。 4. **入口跳转**:正确设置 Trapframe 中的 `epc`,使进程调度后能跳转到 ELF 文件指定的入口点执行。 ## 已知限制 为了在有限的时间内聚焦于操作系统核心原理(如虚拟内存、中断处理、文件系统一致性),实验在非核心路径上进行了一定的简化与抽象。 ### 1. 单核处理器架构 - **设计选择:**系统针对单核 RISC-V 环境设计,未引入多核支持。 - **权衡考量:**简化同步原语:内核态的原子性主要通过关中断来实现,避免了复杂的跨核自旋锁竞争和缓存一致性协议(MESI)的调试开销。 - **聚焦调度逻辑:**将开发重心集中在基于时间片的抢占式轮转调度和上下文切换机制上,而非多核负载均衡。 ### 2. 日志结构文件系统 - **设计选择:**实现了基于 预写式日志 (Write-Ahead Logging, WAL) 的文件系统,支持崩溃一致性 (Crash Consistency)。 - **简化细节:** - **全局日志锁:**为了简化并发控制,文件系统操作采用事务级串行化策略。虽然限制了多进程同时写入的吞吐量,但极大提升了系统的稳定性,杜绝了元数据竞争导致的死锁。 - **定长日志区:**日志区域大小固定,不支持动态扩容,这限制了单次事务能修改的最大块数(即限制了单次写入的最大文件大小),但在嵌入式或教学场景下已足够使用。 - **无细粒度锁:**未实现复杂的细粒度目录锁,而是通过 Inode 级的睡眠锁来管理资源访问。 ### 3. 极简设备驱动模型 - **设计选择:**基于 VirtIO 标准实现块设备驱动。 - **简化细节:**驱动采用同步提交 + 异步中断唤醒的混合模式,未实现复杂的 I/O 调度算法,请求按 FIFO 顺序处理。 --- *References:* * *xv6-riscv: https://github.com/mit-pdos/xv6-riscv* * *RISC-V Privileged Specification*