FPGA自制RISC-V CPU

FPGA自制RISC-V CPU
Photo by Vishnu Mohanan / Unsplash

项目目标

  1. 在正点原子达芬奇pro 赛灵思A7 100T上搭建RISC-V处理器,可以再起之上跑通xv6 OS,学习CPU内部实现的原理和OS的原理
  2. 学习CPU内部实现的原理
  3. 学习OS的原理

前期快速学习路线

学习RISC-V CPU

参考资料:http://riscvbook.com/chinese/RISC-V-Reader-Chinese-v2p1.pdf

第一阶段:指令集与流水线(1-2周)

  • 目标:理解RISC-V指令如何被CPU执行。
  • 内容
    • RV32I指令集:重点掌握lw/sw(访存)、beq/jal(跳转)、算术指令。
    • 5级流水线:取指(IF)、译码(ID)、执行(EX)、访存(MEM)、写回(WB)。这是实现高效CPU的基础。
    • 数据前推(Forwarding):解决RAW(写后读)冒险,避免流水线停顿。

第二阶段:特权架构与异常(1周)

  • 目标:理解操作系统如何接管CPU。
  • 内容
    • CSR寄存器mstatus(状态)、mtvec(异常入口)、mepc(返回地址)、mcause(异常原因)。
    • 异常处理流程:中断(Interrupt) vs 异常(Exception)。当发生缺页或系统调用时,CPU如何跳转到mtvec指向的地址。

第三阶段:内存管理MMU(1周)

  • 目标:理解虚拟地址到物理地址的转换。
  • 内容
    • Sv32分页:RISC-V的页表结构(两级页表)。
    • TLB:页表缓存,加速地址转换。

第一阶段:RISC-V快速入门(2天)

RISC-V是开源指令集,特点是简洁、模块化,xv6运行在RISC-V架构上,因此必须先理解其核心概念:指令格式、基础指令、特权级

1. 核心概念:30分钟建立RISC-V框架

先通过 可视化图解+极简文档 快速了解RISC-V的设计思想:

  • 推荐资源RISC-V官方“快速入门指南”(第1-3章,重点看“指令集概述”“特权架构”)
    ✅ 核心点:
    • 指令格式:RISC-V指令长度固定(32位),分R型(寄存器-寄存器)、I型(立即数)、S型(存储)、B型(分支)等,格式统一(便于硬件实现)。
    • 特权级:3级(M=机器态、S=监管态、U=用户态),xv6内核运行在S态,用户程序在U态,通过“异常/中断”切换特权级(这是OS与硬件交互的核心)。

2. 汇编指令实战:在线模拟器快速上手

RISC-V汇编是理解xv6内核代码的基础,重点掌握 加载/存储(ld/st)、算术逻辑(add/sub)、控制流(beq/bne/jal) 指令。

  • 在线工具RISC-V汇编在线模拟器(Venus,MIT开发,支持单步执行、寄存器/内存查看)
    ✅ 实战任务(30分钟/个):
    1. 基础指令:写一段汇编,实现 a = b + c - d(用 add sub 指令,注意寄存器使用,RISC-V通用寄存器是 x0-x31,x0恒为0)。
    2. 内存访问:用 lw(加载字)从内存地址 0x1000 读取数据,sw(存储字)写入 0x2000
    3. 分支跳转:实现 if (a == b) { c = 1; } else { c = 0; }(用 beq 分支指令)。

3. 特权级与异常:OS内核的“入场券”

xv6内核通过 异常(Exception) 处理系统调用、中断等,必须理解RISC-V的异常机制:

  • 推荐资源RISC-V特权架构手册(精简版)(第3-4章,重点看“异常原因码”“中断处理流程”)
    ✅ 核心点:
    • 异常触发:用户态程序执行 ecall 指令(系统调用)或访问非法内存时,会触发异常,CPU切换到S态(监管态),跳转到异常处理入口(stvec 寄存器指定地址)。
    • xv6中的异常处理:内核初始化时设置 stvec 为异常处理函数 trapvec,后续所有系统调用(如 fork exec)都通过这个流程进入内核。

第二阶段:xv6核心模块学习(3天)

xv6是MIT为RISC-V设计的迷你OS(约1万行C+汇编代码),结构清晰,涵盖OS核心功能。重点学 启动流程、进程管理、内存管理,结合源码和在线实验平台。

1. xv6环境搭建:在线/本地二选一

无需复杂配置,推荐 在线环境 快速上手:

  • 在线平台MIT 6.S081 xv6实验环境(官方推荐,需注册GitHub账号,通过Docker一键启动环境,含xv6源码和QEMU模拟器)
  • 本地简化版:如果网络受限,可直接下载xv6源码(GitHub仓库),用Docker命令 docker run -it --rm -v $(pwd):/xv6 riscv64-unknown-elf 启动编译环境。

2. 启动流程:从“加电”到“用户程序运行”

理解xv6如何从硬件启动到加载内核,再到运行第一个用户程序(init):

  • 推荐资源:xv6官方文档 《xv6 Book》(第1章“启动”,第2章“进程”)
    ✅ 核心步骤(结合源码):
    1. 硬件启动:RISC-V CPU加电后,从地址 0x100000(ROM)执行引导程序(bootloader),加载xv6内核到内存。
    2. 内核初始化:执行 kernel/start.c 中的 start 函数,初始化页表(内存虚拟化)、中断控制器(PLIC)、进程调度器。
    3. 创建第一个进程:内核通过 user/init.c 创建 init 进程(用户态),后续所有进程由 init 衍生。

3. 进程管理:从fork到调度

进程是OS的核心,xv6的进程管理包含 进程创建(fork)、调度(scheduler)、切换(context switch),直接对应RISC-V的特权级切换和上下文保存。

  • 推荐实验:MIT 6.S081实验1 “Xv6 and Unix utilities”(修改xv6源码,实现简单命令,如 sleep pingpong
    ✅ 重点源码文件:
    • kernel/proc.c:进程控制块(struct proc)、fork() 实现(复制页表、上下文)、scheduler() 调度算法(Round-Robin)。
    • kernel/swtch.S:汇编实现的上下文切换(swtch 函数,保存/恢复寄存器,切换栈)。

4. 内存管理:分页与虚拟地址

RISC-V的内存虚拟化通过 分页(Paging) 实现,xv6通过页表将用户虚拟地址映射到物理地址,隔离进程内存空间。

  • 推荐资源:xv6 Book第3章“内存管理” + RISC-V分页机制图解
    ✅ 核心点:
    • 页表结构:xv6使用三级页表(RV64架构),每个页表项(PTE)包含物理页号、权限位(如读/写/执行)。
    • 用户内存隔离:每个进程有独立页表,通过 satp 寄存器(RISC-V特权寄存器)切换页表,实现地址空间隔离。

第三阶段:实战巩固(2天)

通过 修改xv6源码 验证理解,快速掌握“理论→代码”的映射。

实验1:添加系统调用(3小时)

目标:在xv6中添加一个自定义系统调用 sys_hello(),用户程序调用后输出“Hello RISC-V xv6!”。

  • 步骤
    1. 修改 kernel/syscall.h:添加系统调用号(如 SYS_hello 22)。
    2. 修改 kernel/syscall.c:添加 sys_hello 函数实现(调用 printf 输出字符串),并在 syscalls 数组中注册。
    3. 修改 user/user.h 和 user/usys.pl:添加用户态函数声明和系统调用封装。
    4. 编写用户程序 user/hello.c,调用 hello(),编译运行xv6,执行 hello 命令验证效果。

实验2:跟踪进程切换(3小时)

目标:在xv6调度器中添加打印,观察进程切换过程(结合RISC-V上下文切换)。

  • 步骤
    1. 修改 kernel/proc.c 的 scheduler() 函数,在切换进程前打印当前进程PID和目标进程PID。
    2. 运行xv6,执行 fork pingpong 等命令,观察控制台输出的进程切换顺序,理解Round-Robin调度逻辑。

核心资源汇总

学习内容在线资源特点
RISC-V基础Venus汇编模拟器在线运行汇编,单步调试
RISC-V特权级RISC-V特权手册(精简版)聚焦异常处理、特权寄存器
xv6源码+文档xv6官方GitHub + xv6 Book源码注释清晰,文档配套实验
实验指导MIT 6.S081课程实验分步骤引导,覆盖核心模块

学习路径总结(7天规划)

  • Day1-2:RISC-V基础(指令集+汇编+特权级),用Venus完成3个汇编小实验;
  • Day3-4:xv6启动流程+进程管理,阅读 proc.c swtch.S 源码,理解fork和调度;
  • Day5-6:xv6内存管理+文件系统,完成“添加系统调用”实验;
  • Day7:综合实验(跟踪进程切换),整理笔记,画xv6核心模块关系图(用Mermaid!)。

关键原则“源码优先,实验驱动”。xv6源码量少,直接读 kernel/ 目录下的核心文件(proc.c vm.c syscall.c),遇到不懂的RISC-V指令或寄存器,回头查手册。通过修改源码并运行观察效果,比纯看文档效率高10倍!

学习OS原理及xv6 OS设计思路

参考书籍:《Operating Systems: Three Easy Pieces》
《深入理解计算机系统(原书第3版)》
参考资料:《xv6操作系统详解》 Frans Kaashoek, Robert Morris(MIT 6.828课程教材)官网 https://pdos.csail.mit.edu/6.828/2020/xv6.html

OS核心特性

  1. 核心模块(进程、内存、调度、文件系统)
  2. 虚拟化、并发、持久化

一、核心概念速成:10小时掌握OS骨架

直接瞄准OS最核心的3个底层逻辑(虚拟化、并发、持久化),用“极简教程+图解”快速打通脉络。

1. MIT 6.828 精简笔记(xv6核心概念)

  • 资源MIT 6.828 课程精简笔记(英文,可配合机翻)
  • 特点
    • MIT操作系统课程的核心讲义,每章10-15分钟可读完,聚焦“进程创建(fork)、内存分页、文件系统实现”等硬核概念,用xv6迷你内核的代码片段举例(如fork()系统调用的实现逻辑)。
    • 跳过复杂数学推导,直接讲“OS为什么要这么设计”(如分页解决内存碎片化、调度解决CPU利用率)。
  • 重点看:Lec 1(OS概述)、Lec 3(进程)、Lec 4(内存)、Lec 7(文件系统)—— 4章内容,2小时内搞定核心骨架。

2. 《OS核心概念图解》(中文在线版)

  • 资源小林coding的“操作系统图解”系列(公众号/网站,免费)
  • 特点
    • 国内技术博主出品,纯图解+白话解释,没有代码,适合快速建立“视觉化认知”。
    • 覆盖进程调度(如FCFS、RR算法动画)、内存分页(页表如何映射虚拟地址)、文件系统(inode结构)等核心模块,每篇文章5-8分钟,图文并茂(例:用“图书馆借书”类比内存分页)。
  • 推荐阅读顺序:进程管理 → 内存管理 → 调度算法 → 文件系统(共10篇,1小时内看完)。

3. Crash Course Computer Science: OS专题(视频)

  • 资源B站“速成课:计算机科学”第18-21集(中文字幕,每集10分钟)
  • 特点
    • 国外经典科普视频,用动画演示OS如何“管理硬件资源”:从“单任务→多任务”的演进、进程切换的过程、死锁的例子(如哲学家问题动画),轻松理解OS的“存在意义”。
  • 适合:喜欢通过“故事化”快速建立宏观认知的学习者,4集共40分钟,看完就知道OS到底在干嘛。

二、可视化与交互:边玩边学抽象概念

OS的很多概念(如内存分页、调度算法)抽象难懂,交互式工具能帮你“动手验证”,比看书快10倍。

1. Pintos OS模拟实验(简化版)

  • 资源Pintos可视化平台(在线模拟,无需本地配置)
  • 特点
    • 迷你OS教学工具,可在线模拟“进程调度”(如调整RR调度的时间片,观察进程切换)、“内存分页”(手动分配物理页,看虚拟地址如何映射),甚至能修改简单代码(如调度算法)并立即运行看效果。
  • 推荐操作:花30分钟玩“调度算法模拟器”,对比FCFS、SJF、RR的执行效率,直观理解“为什么需要复杂调度”。

2. OS内存管理可视化(国内工具)

  • 资源菜鸟教程“内存管理模拟器”
  • 特点
    • 网页版工具,可模拟“连续内存分配”(首次适应、最佳适应算法)和“分页管理”(页表查找过程),拖动鼠标就能操作,实时显示内存使用情况,5分钟搞懂“内存碎片怎么产生的”。

三、实战导向:1个下午动手实现OS核心功能

快速学习的关键是“用输出倒逼输入”,通过极简实验理解OS“如何干活”,比纯理论更深刻。

1. “用C写一个迷你进程调度器”(在线实验)

  • 资源LeetCode Explore“操作系统实战”(中文,含代码模板)
  • 任务:实现一个简单的“Round-Robin调度器”(时间片轮转),模拟3个进程的切换过程,代码量仅50行。
  • 收获:通过实现schedule()函数,理解“进程PCB(进程控制块)”的作用、上下文切换的本质(保存/恢复寄存器)。

2. xv6迷你内核“Hello World”(1小时入门)

  • 资源xv6在线环境(可配合国内镜像教程
  • 任务:在xv6中添加一个系统调用(如sys_hello(),输出“Hello OS”),编译运行。
  • 收获:5步完成(修改系统调用表→实现函数→编译内核→运行),直观感受“用户态如何通过系统调用与内核交互”,理解OS的“分层设计”。

四、视频速成课:2小时搞定核心考点

如果偏爱“听讲解”,推荐短平快的视频课,直接划重点,跳过冗余内容。

1. B站“操作系统速成课”(南京大学袁春风)

  • 资源袁春风《操作系统》精简版(选看P2-P5:进程、内存、调度、文件系统,共2小时)
  • 特点:国内高校名师,直接讲考点级核心概念(如进程状态转换图、页面置换算法(LRU)、文件系统inode结构),适合快速应对面试/考试中的OS基础题。

2. YouTube“OS in 100 Seconds”系列(超短科普)

  • 资源OS in 100 Seconds(英文,100秒/个概念,可配合字幕)
  • 特点:用动画快速解释“进程vs线程”“虚拟内存”“内核态vs用户态”等高频概念,每个视频1-2分钟,碎片化时间就能学(例:用“办公室前台”类比内核,“员工”类比用户程序)。

五、最后:30分钟梳理知识框架

学完后,用思维导图工具(如XMind)快速整理核心模块,确保“不遗漏关键点”:

TEXT1操作系统
2├─ 核心目标:管理硬件(CPU/内存/磁盘),给应用提供抽象接口
3├─ 三大支柱:
4│ ├─ 虚拟化:CPU虚拟化(进程/线程)、内存虚拟化(分页/分段)
5│ ├─ 并发:调度算法(RR/FCFS/SJF)、同步互斥(信号量/锁)
6│ └─ 持久化:文件系统(inode/数据块)、I/O管理
7└─ 关键问题:死锁(预防/避免)、内存泄漏、缓存策略(LRU)

学习路径建议(总耗时:1天内)

  1. 上午2小时:看Crash Course视频(40分钟)+ 小林coding图解(1小时)+ MIT精简笔记(20分钟),建立宏观认知;
  2. 下午3小时:玩Pintos调度模拟器(30分钟)+ 实现迷你调度器(1小时)+ xv6系统调用实验(1.5小时),动手验证;
  3. 晚上30分钟:用思维导图梳理框架,标记“不懂的点”(如页表具体如何映射),后续按需深入。