前言
xv6 是 MIT 基于 Unix 第六版思想实现的教学操作系统。它代码规模相对较小,但包含了操作系统中许多关键机制,例如进程管理、系统调用、内存管理、文件系统、锁与并发、中断处理等。通过学习 xv6,可以在较低的复杂度下理解现代操作系统的基本设计思想。 由于 xv6 本身面向教学,很多实现并不追求工业级完整性,但它非常适合理解操作系统的核心原理。希望通过这些记录,能够把抽象的操作系统概念落实到具体代码中,也为后续学习 Linux 内核、系统编程和底层开发打下基础。
安装编译工具
xv6系统是一个基于riscv架构的精简内核系统,在电脑上我们依赖于QEMU虚拟机进行运行。所以在开始学习前我们需要先配置好riscv编译工具链和QEMU虚拟机。
重要
注意 本文安装环境只考虑 macOS 下配置。如果需要在 Linux / Windows 下配置环境,请参考官方指南。
安装开发者工具和包管理器
使用mac开发肯定绕不开xcode工具,所以第一步要先安装xcode命令行工具
xcode-select --install之后通过官方脚本安装包管理器Homebrew
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"提示
提示 Homebrew官方脚本默认使用官方源安装,国内访问速度较慢。网络环境不行的可以使用此仓库国内源脚本。
安装 RISC-V compiler toolchain
之后使用brew安装riscv编译工具链
brew tap riscv/riscv
brew install riscv-tools提示
提示 如果安装后终端找不到交叉编译命令,可根据芯片架构在
~/.zshrc中手动将工具链目录(Apple Silicon 为/opt/homebrew/opt/riscv-gnu-toolchain/bin,Intel Mac 为/usr/local/opt/riscv-gnu-toolchain/bin)加入PATH。
安装 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 系统会开始运行,之后即可进行调试和分析。
使用 VS Code 运行并调试
目前 xv6 已经可以正常运行和调试了,但为了后续学习的方便,配置一个顺手的图形化调试界面依然很有必要。这里以 VS Code 为例进行配置。
先在仓库根目录下建立.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
}
]
}
]
}提示
提示 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.*"
}
}
}
]
}提示
提示 这里make qemu 的参数CPUS=1是为了限制xv6运行时的cpu个数。xv6支持多cpu,默认情况下会启用3个cpu。这里为了便于调试设置为1个cpu。
之后在VSCode里面直接点击调试即可开始调试
调试用户程序
因为 xv6 内核和用户程序各自生成独立的 ELF 符号文件,要调试用户程序需要先导入对应的用户程序符号表。
用户程序编译后会生成在仓库的 user/ 目录下,以 cat 为例,编译后的二进制文件位于 user/_cat。
在 VS Code 调试控制台中输入:
-exec file user/_cat(如果想同时保留内核符号,也可以改用 -exec add-symbol-file user/_cat)导入符号表后即可正常调试。
