前言
xv6 是 MIT 基于 Unix 第六版思想实现的教学操作系统。它代码规模相对较小,但包含了操作系统中许多关键机制,例如进程管理、系统调用、内存管理、文件系统、锁与并发、中断处理等。通过学习 xv6,可以在较低的复杂度下理解现代操作系统的基本设计思想。 由于 xv6 本身面向教学,很多实现并不追求工业级完整性,但它非常适合理解操作系统的核心原理。希望通过这些记录,能够把抽象的操作系统概念落实到具体代码中,也为后续学习 Linux 内核、系统编程和底层开发打下基础。
安装编译工具
xv6系统是一个基于riscv架构的精简内核系统,在电脑上我们依赖于QEMU虚拟机进行运行。所以在开始学习前我们需要先配置好riscv编译工具链和QEMU虚拟机。
[!IMPORTANT] 注意 本文安装环境只考虑macOS下配置。如果需要在Linux/Windowns下配置环境,请参考官方指南
安装开发者工具和包管理器
使用mac开发肯定绕不开xcode工具,所以第一步要先安装xcode命令行工具
xcode-select --install
之后通过官方脚本安装包管理器Homebrew
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
[!TIP] 提示 Homebrew官方脚本默认使用官方源安装,国内访问速度较慢。网络环境不行的可以使用此仓库国内源脚本。
安装 RISC-V compiler toolchain
之后使用brew安装riscv编译工具链
brew tap riscv/riscv
brew install riscv-tools
[!TIP] 提示 Homebrew不会把工具自动链接到
/usr/local,需要手动在~/.zshrc中添加环境变量PATH=$PATH:/usr/local/opt/riscv-gnu-toolchain/bin
安装 QEMU
之后安装QEMU虚拟机以运行系统
brew install qemu安装GDB调试器
macOS下,brew安装的riscv编译工具链并不包含GDB调试器。为了以后的调试,需要额外安装GDB调试器
brew install riscv64-elf-gdb配置并运行
拉取项目代码
使用git从MIT的仓库拉取项目源码
git clone git://g.csail.mit.edu/xv6-labs-2025在终端中编译运行
先切换到仓库目录
cd xv6-labs-2025
之后直接使用make qemu即可自动编译系统并在qemu中运行
❯ make qemu
mv -f fs.img fs.img.bk
mkfs/mkfs fs.img README user/findtest.sh user/sixfive.txt user/_cat user/_echo user/_forktest user/_grep user/_init user/_kill user/_ln user/_ls user/_mkdir user/_rm user/_sh user/_stressfs user/_usertests user/_grind user/_wc user/_zombie user/_logstress user/_forphan user/_dorphan user/_memdump
nmeta 47 (boot, super, log blocks 31, inode blocks 13, bitmap blocks 1) blocks 1953 total 2000
balloc: first 990 blocks have been allocated
balloc: write bitmap block at sector 46
qemu-system-riscv64 -machine virt -bios none -kernel kernel/kernel -m 128M -smp 3 -nographic -global virtio-mmio.force-legacy=false -drive file=fs.img,if=none,format=raw,id=x0 -device virtio-blk-device,drive=x0,bus=virtio-mmio-bus.0
xv6 kernel is booting
hart 1 starting
hart 2 starting
init: starting sh
$ 调试代码
在终端中使用GDB调试
在终端中调试,先使用make qemu-gdb编译运行xv6系统,并等待调试器链接
make qemu-gdb
之后打开另一个终端,运行gdb来连接调试
riscv64-elf-gdb kernel/kernel
连接成功后xv6系统会开始运行,之后即可进行调试和分析。
使用VSCode运行并调试
目前已经xv6已经可以正常运行和调试了,但为了以后学习的方便,配置一个顺手的工具还是很必要的。这里选用VSCode进行调试和开发。
先在仓库根目录下建立.vscode配置文件夹
mkdir .vscode
创建.vscode/launch.json,并写入以下内容
{
"version": "0.2.0",
"configurations": [
{
"name": "debug xv6",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/kernel/kernel",
"args": [],
"stopAtEntry": true,
"cwd": "${workspaceFolder}",
"miDebuggerServerAddress": "localhost:25501",
"preLaunchTask": "xv6: qemu-gdb CPUS=1",
"miDebuggerPath": "riscv64-elf-gdb",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "pretty printing",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
}
]
}
[!TIP] 提示 miDebuggerPath参数为gdb调试器的路径,请根据你具体安装的调试器更改。
创建.vscode/tasks.json,并写入以下内容
{
"version": "2.0.0",
"tasks": [
{
"label": "xv6: qemu-gdb CPUS=1",
"type": "shell",
"command": "make CPUS=1 qemu-gdb",
"isBackground": true,
"problemMatcher": {
"pattern": [
{
"regexp": ".",
"file": 1,
"location": 2,
"message": 3
}
],
"background": {
"activeOnStart": true,
"beginsPattern": ".*",
"endsPattern": ".*gdb.*"
}
}
}
]
}
[!TIP] 提示 这里make qemu 的参数CPUS=1是为了限制xv6运行时的cpu个数。xv6支持多cpu,默认情况下会启用3个cpu。这里为了便于调试设置为1个cpu。
之后在VSCode里面直接点击调试即可开始调试
调试用户程序
因为xv6系统程序和用户程序是两套elf符号,所以要调试用户程序需要先导入用户程序的符号表,之后才能进行调试。 符号表一般在编译时会生成在源文件目录下,以cat举例,编译后他的符号表会生成在/user/_cat。 在GDB终端中输入
-exec file /user/_cat
导入符号表,之后即可正常调试。