Article

MIT 6.1810:macOS 下环境准备与XV6源码运行

xv6系统运行截图

前言

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

导入符号表,之后即可正常调试。

参考资料

站内搜索

找到你感兴趣的内容

输入关键词开始搜索