灵感来源:From the Transistor to the Web Browser。
招聘很难,很多现代计算机科学教育质量不高,很难找到真正理解现代计算机技术原理的人。
现在课程内容已经整理完成,并且只涉及软件部分。距离实际应用更近了一步。
第 1 节 - 介绍 (0.5 周)
跳过晶体管的详细讨论。
关于晶体管
课程概述。讲解如何用晶体管构建 FPGA,以及 IC 实际上是晶体管的集合。理解查找表 (LUT) 和相关概念。简要介绍晶体管的理论,强调所有项目必须相互依赖,因此本课程中不会从头开始构建晶体管。
仿真技术
讨论在真实硬件上实践的局限性,并介绍仿真作为解决方案。解释如何使用 Verilator 等工具进行硬件仿真,让任何拥有计算机的人都可以参与课程。
第 2 节 - 启动 (0.5 周)
硬件编程使用什么语言?
闪烁 LED (Verilog/Bluespec, 10)
你的第一个程序:让 LED 闪烁。运行模拟器并学习 Verilog/Bluespec 的基础知识。这个简单的任务帮助你理解硬件描述语言所需的工作流程和工具。
构建 UART (Verilog/Bluespec, 100)
深入学习 Verilog/Bluespec,通过复制一个真实的 UART。介绍内存映射 I/O (MMIO) 的概念。实现一个串行测试回显程序和 LED 控制,以巩固你的理解。
第 3 节 - 处理器 (3 周)
处理器是什么?
编写汇编器 (Rust, 500)
用 Rust 编写一个汇编器。这个简单但重要的任务教你 RISC-V 汇编。最初,汇编器输出二进制文件,之后会扩展以支持链接。
构建 RISC-V CPU(Bluespec, 1500)
将其分为几个子章节。首先构建一个简单的流水线:解码、获取、执行。讨论内存需求和限制,例如 BRAM 和 SRAM。确保 CPU 既可模拟又可综合。
编写启动 ROM(汇编, 40)
用汇编编写一个启动 ROM,以支持通过串口下载代码到 RAM 中。这个 ROM 会被烧录到 FPGA 图像中,并运行简单的测试程序。
第 4 节 - 编译器(3 周)
高级语言
构建 C 编译器(Haskell, 2000)
用 Haskell 编写一个 C 编译器,涵盖编译器设计的基础知识。本节包括编写解析器和生成 RISC-V 汇编。将任务分为子章节以便更好地理解。
构建链接器(Rust, 300)
用 Rust 编写一个链接器以生成 ELF 文件。如果你理解链接的基础知识,这个任务应该很简单。使用链接器与 QEMU 和 semihosting 进行测试。
libc + malloc(C, 500)
实现基本的 libc 函数,如 memcpy、memset 和 printf,以及一个简单的 malloc。这为更复杂的程序奠定基础。
构建以太网控制器(Bluespec, 200)
与真实的 PHY 接口并仔细设计 MMIO。这项任务涉及硬件和软件组件。
编写引导程序(Rust, 300)
用 Rust 编写一个引导程序,通过 UDP 引导内核。引导程序最初通过串口下载,之后会嵌入 FPGA 图像中。
第 5 节 - 操作系统(3 周)
操作系统软件
构建 MMU(Verilog, 1000)
设计一个 RISC-V MMU。解释 TLBs (Translation Lookaside Buffers) 的作用和其他相关概念。如果 FPGA 需要,还可能需要构建一个内存控制器。将 MMU 与引导程序集成,添加初始化代码。
构建操作系统(Rust, 2500)
开发一个类似 UNIX 的操作系统,支持基本的用户空间线程。实现系统调用,例如 open、read、write、close、fork、execve、wait、sleep、exit、mmap、munmap 和 mprotect。考虑你使用的调试接口,从 printf 语句到可能在内核中的 gdbremote stub。将任务分为子章节以便更好地理解。
与 SD 卡通信(Bluespec, 150)
实现最终的硬件模块:SD 卡接口和驱动程序。
FAT 文件系统(Rust, 300)
实现一个简单的文件系统,如 FAT (File Allocation Table)。处理基本的文件操作,如读取、写入和目录管理。
基本用户空间程序(Rust, 250)
开发你的第一个用户空间程序。实现基本工具,如 init、一个简单的 shell 和命令,例如 download、cat、ls 和 rm。这些程序将提供一个与操作系统交互的基本用户界面。
第 6 节 - 浏览器(1 周)
连接到网络。
构建 TCP 栈(Rust, 500)
实现一个 TCP 栈,可能在内核中编写。将以太网驱动程序集成到内核中,并添加对网络系统调用的支持,例如 send、recv、bind 和 connect。
telnetd 守护进程(Rust, 50)
用 Rust 编写一个简单的 telnetd 守护进程。这允许多个用户使用 telnet 同时连接,实际上创建了一个绑定 shell。
节省空间的动态链接(Rust, 300)
解释并实现动态链接以节省空间。演示动态链接器如何作为用户空间程序运行。讨论链接器的必要改动。
创建文本浏览器(Rust, 500+)
使用 ANSI 和终端功能创建一个“漂亮”的基于文本的 web 浏览器。浏览器应当是动态链接的,并且功能尽可能丰富,重点是终端中的 web 内容呈现。
第 7 节 - 硬件(1 周)
在真实硬件上运行。
与 FPGA 通信(Rust, 200)
编写一个小程序,控制 USB MCU 以位打 JTAG 命令,从而与 FPGA 通信。
构建 FPGA 板
设计并构建一个 FPGA 板。这包括 FPGA BGA 回流、FPGA 闪存、50MHz 时钟、USB JTAG 端口和闪存 (使用 Cypress USB MCU 进行 JTAG)、LED、重置按钮、USB 供电串口 (USB-FTDI)、SD 卡槽和以太网端口。
可选地,设计一个带有额外功能的扩展板,例如主机 USB 端口、NTSC TV 输出、ISA 端口和 PS/2 连接器。使用烤箱和万用表温度计进行回流焊接。
启动测试
编译并下载 Verilog 代码到 FPGA 板。这一步包括测试和验证硬件功能。
第 8 节 - 并行和分布式计算(3 周)
使浏览器并行化(Rust, 200)
修改你的 web 浏览器以利用并行处理,提升性能和响应速度。
开发多线程 web 服务器(Rust, 200)
用 Rust 开发一个多线程 web 服务器。这个服务器应该能够高效处理多个并发连接。
并行 Map-Reduce(Rust, 500)
用 Rust 实现一个并行 Map-Reduce 框架。这将涉及将任务拆分、分布到多个线程或进程中,并汇总结果。
分布式键值存储(Rust, 500)
使用 RAFT 共识算法创建一个分布式键值存储系统,以确保数据一致性和容错。
第 9 节 - 区块链(3 周)
探索区块链技术的基础和应用。
基本加密学
介绍并解释理解区块链技术所必需的基础加密概念。这包括:
- 哈希函数: 理解 SHA-256 和其他加密哈希函数。
- 公钥加密: 介绍 RSA、ECC 和数字签名的概念。
- 对称加密与非对称加密: 何时何地使用每种类型。
- 默克尔树: 理解它们在区块链中确保数据完整性的重要性。
其他共识算法
探索各种共识算法,除了众所周知的工作量证明 (PoW) 之外。这包括:
- 权益证明 (PoS): 它如何工作及其相对于 PoW 的优势。
- 委托权益证明 (DPoS): 委托人在共识过程中的作用。
- 实用拜占庭容错 (PBFT): 理解这个算法如何在分布式系统中实现共识。
- Raft 和 Paxos: 详细解释这些用于分布式计算的共识算法,并与区块链共识机制进行比较。
你的第一个区块链(Rust, 500)
用 Rust 从头开始实现一个简单的区块链。