文章目录
- xv6内核环境配置
- 1.开发环境的准备
- (1).如果日常用Linux
- (2).Windows的回合
- #1.两个常见方法
- #2.wsl的一点安装细节
- #3.记得升级成wsl-2
- (3).如果你是macOS
- #1.一些起因
- #2.最乐的一集
- #3.Homebrew的配置
- #4.mac用户的特权
- 2.先换apt源
- 3.安装xv6的依赖
- 4.克隆RISC-V GNU 编译器工具链
- 5.编译RISC-V GNU 编译器工具链
- 5.安装QEMU-5.1.0
- 6.克隆xv6内核代码,编译,QEMU启动
- 7.GDB远程调试xv6(仅限WSL)
xv6内核环境配置
这学期的操作系统实验课我们采用了MIT的xv6-riscv内核,所以要配置对应的qemu环境以及一套可用的RISC-V的编译工具链,理论上讲,是有一点点困难的,这里我总结了一下配置的方法,可能会对你有一点帮助
1.开发环境的准备
(1).如果日常用Linux
如果你已经日常使用Linux了,那直接跳到3,直接安装依赖然后克隆仓库安装即可,我想你都有这能力了,大概率也不需要看这一篇博客了
(2).Windows的回合
#1.两个常见方法
大部分情况实际上则是大家使用的是Windows,并且很大一部分人用的是Windows 10/11,你当然可以直接采用经典的VMware Workstation Pro/Oracle VirtualBox安装Ubuntu-23.10虚拟机的流程即可,但对于Windows 10/11,这里更加推荐你使用Windows Subsytem for Linux(WSL),这是微软从Windows 10的某一次大更新之后开始为Windows准备的Linux子系统,它基本上能以一个应用的形式存在于你的Windows当中,在WSL下配置xv6内核会非常方便
#2.wsl的一点安装细节
这里我就不细讲WSL的安装方法了,主要是几个步骤:在控制面板的程序与功能中,点击左侧的启用或关闭 Windows 功能,在Hyper-V,Windows 虚拟机监控程序平台,适用于 Linux 的 Windows 子系统以及虚拟机平台前打钩(这一步中如果你用的是家庭版系统可能没有Hyper-V选项,不过这并不重要),然后点击确定,Windows 会帮你完成这些功能的添加,之后需要重启一次机器
机器重启后,打开尘封已久的Microsoft Store,在搜索栏搜索Ubuntu,你应该能看到好几个结果,这里推荐选择Ubuntu 22.04.3 LTS,能出现在Microsoft Store里的Ubuntu一般都是LTS也就是长期支持版本,怎么说也相对是比较稳定的
安装完成后直接启动,这一步可能会出现非常多的问题,你需要自行上网查阅资料解决,有几个常见的问题,比如需要你去BIOS中开启虚拟化的,这个就在开机时按住某个按键(自己搜搜看电脑型号对应的按键是什么),然后找到类似SVM Mode或者虚拟化之类的选项,将它启用即可
#3.记得升级成wsl-2
现在安装的WSL一般已经是WSL-2了,为了后续的操作,我也推荐你把WSL升级为WSL-2,如果是手动升级的,你还需要在powershell里使用wsl --set-version指令进行已安装的发行版的wsl版本更换,这里也不再赘述
(3).如果你是macOS
#1.一些起因
最近我也整了一台mac,因为mac现在全系转向arm,其实有很多事情是做不了的,这也的确是一个麻烦的问题,然后昨天我去查阅了一下MIT 6.S081也就是xv6这个内核对应的课程Operating System Engineering的课程网站,我发现课程提供的的配置教程中竟然也提供了macOS的安装方法
#2.最乐的一集
最戏剧化的一幕来了,我本来以为macOS也要走后面章节中那些麻烦的git clone以及make的流程,没想到用homebrew几行代码就解决了,配置好代理的情况下只要五分钟,你就可以直接make qemu启动xv6了,所以macOS非常适合完成xv6的环境配置
顺便提一嘴,homebrew是一个类似于debian下的apt,centos下的yum以及最近出现的windows下的winget的包管理器,很多软件包你都可以用过homebrew快速安装,常用的指令如下:
brew search 软件包名 # 查询软件包
brew install 软件包名 # 安装软件包
brew uninstall 软件包名 # 卸载软件包
这个软件比你想的可能会多一点,在apt下我们一般也就装一些基本插件,但是brew里面我们甚至可以安装有图形界面的mac版bilibili,你只需要:
brew install bilibili
这样就安装完毕了,非常优雅,macOS用户后面就可以直接采用brew完成环境的配置
#3.Homebrew的配置
其实刚刚的配置手册中已经有了macOS连带配置homebrew的流程了,但是通过这个方式安装的homebrew还需要手动换源,之前我看到有博客制作了一些能够自动安装并切换国内源的脚本,我自己也是使用这个的,因此你可以参考这篇博客来完成Homebrew的安装:Homebrew国内如何自动安装(国内地址)(Mac & Linux)
#4.mac用户的特权
到这儿我相信你的Homebrew已经装好了,接下来你只需要在你的终端里输入:
xcode-select --install
这一行代码用于安装macOS下的开发者工具,然后用brew安装git(后续需要下载仓库代码):
brew install git
之后就可以三条指令安装RISC-V的编译器工具链了:
brew tap riscv/riscv
brew install riscv-tools
PATH=$PATH:/usr/local/opt/riscv-gnu-toolchain/bin
前面两行代码负责安装riscv-tools,最后一行则是把它加入到环境变量中,需要注意的是,第三行的路径可能会因为芯片而产生差异,在x86-64的环境下,homebrew的安装目录默认并不在/usr/local/opt下,你需要把第三行代码修改为真实安装的目录
接下来安装一下QEMU:
brew install qemu
好了,结束了,接下来你可以直接跳到6了,后面的编译之类的工作不需要做了,遥遥领先
2.先换apt源
如果是全新安装的Ubuntu,需要首先更换apt源,否则后续所有的apt-get install操作都会非常慢,这里推荐更换清华源(来自清华大学TUNA协会),进入之后点击开源软件镜像站,向下翻找到ubuntu,点击右边的问号:
进入之后你能看到对应于Ubuntu-22.04 LTS的一串代码:
# 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-updates main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-updates main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-backports main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-backports main restricted universe multiverse
deb http://security.ubuntu.com/ubuntu/ jammy-security main restricted universe multiverse
# deb-src http://security.ubuntu.com/ubuntu/ jammy-security main restricted universe multiverse
# 预发布软件源,不建议启用
# deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-proposed main restricted universe multiverse
# # deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-proposed main restricted universe multiverse
这固然很好,但是这上面没有对最新的Ubuntu-23.10 (mantic)进行适配,如果你选择的是Ubuntu-22.04及之前的版本,可以直接在上面点选更换,否则如果是23.10,就把上面所有的jammy更换为mantic:
# 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ mantic main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ mantic main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ mantic-updates main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ mantic-updates main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ mantic-backports main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ mantic-backports main restricted universe multiverse
deb http://security.ubuntu.com/ubuntu/ mantic-security main restricted universe multiverse
# deb-src http://security.ubuntu.com/ubuntu/ mantic-security main restricted universe multiverse
# 预发布软件源,不建议启用
# deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ mantic-proposed main restricted universe multiverse
# # deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ mantic-proposed main restricted universe multiverse
这时候在你的Linux终端里输入:
cd /etc/apt
sudo mv sources.list sources.list.b
sudo vim sources.list # 如果提示不存在vim,那就换用下面这一条
# 或者,上下两条二选一
sudo vi sources.list
进入之后首先按i,当左下角显示INSERT的时候,把上面的代码复制粘贴进去,然后按下Esc键,之后输入 :wq(这个冒号也要输入!)这样就可以保存并退出vim/vi了,然后接下来在命令行中输入:
sudo apt-get update
等更新完了之后,就可以完成后续的操作了。如果你用的是arm版的ubuntu,请在刚刚进入镜像站的那个地方找到ubuntu-ports,点击旁边的问号,arm版的ubuntu需要使用ubuntu-ports源而不是ubuntu源(不过,官网的arm版ubuntu是没有图形界面的,我觉得你要是自己能装,你也不需要我告诉你应该干什么了)
3.安装xv6的依赖
最重要的是mpc, mpfr和gmp,这三个是gcc的依赖,没有的话会在后续的编译步骤中报错
sudo apt-get install git build-essential gdb-multiarch qemu-system-misc gcc-riscv64-linux-gnu binutils-riscv64-linux-gnu
sudo apt-get install autoconf automake autotools-dev curl libmpc-dev libmpfr-dev libgmp-dev gawk bison flex texinfo gperf libtool patchutils bc zlib1g-dev libexpat-dev
4.克隆RISC-V GNU 编译器工具链
GitHub不加速是没有办法直接git clone滴~这里用gitee的riscv-gnu-toolchain进行一个镜像站的拉取(可能还是需要使用科学上网,所以这里推荐使用WSL-2),这个方法来自riscv-gnu-toolchain 下载编译 及 xv6 os编译试运行这篇博客,效率还是很不错的
git clone https://gitee.com/mirrors/riscv-gnu-toolchain
cd riscv-gnu-toolchain
git clone --recursive https://gitee.com/mirrors/qemu.git
git clone --recursive https://gitee.com/mirrors/riscv-newlib.git
git clone --recursive https://gitee.com/mirrors/riscv-binutils-gdb.git
git clone --recursive https://gitee.com/mirrors/riscv-dejagnu.git
git clone --recursive https://gitee.com/mirrors/riscv-glibc.git
# riscv-gcc 超过1G,会clone出错,这里设置拉取最近一次提交的版本
git clone --depth 1 https://gitee.com/mirrors/riscv-gcc.git
如果不幸,在git clone过程中多次失败然后中断,你需要删除已经被git clone创建的目录,使用如下命令进行删除:
rm -rf 文件夹路径
严重警告:rm -rf是一个非常危险的指令,在敲下回车之前一定要仔细检查你输入的路径是否正确,例如在克隆qemu仓库的时候出错,你应该输入rm -rf qemu,这样就好了,不要加上多余的内容
5.编译RISC-V GNU 编译器工具链
上述克隆仓库后,需要进行编译
# 首先确定自己在~/riscv-gnu-toolchain目录下
mkdir riscv-gdb riscv-binutils
cd riscv-binutils-gdb
cp -a * ../riscv-gdb
cp -a * ../riscv-binutils
在确保~/riscv-gnu-toolchain/riscv-gdb和riscv-binutils两个文件夹中确实有了文件之后,接下来进行编译操作:
cd ~/riscv-gnu-toolchain
./configure --prefix=/usr/local
sudo make -j4 # 这里的数字意思是用4线程编译,如果你的机器核比较多,可以开更多,比如我是make -j16
编译需要等待非常长的时间,期间你的CPU占用率可能会飙升到全核100%,内存占用率也可能会瞬间提高,请务必在编译命令开始前关闭一些不必要的程序,例如浏览器等
5.安装QEMU-5.1.0
xv6内核的允许需要用到QEMU,所以这里需要安装QEMU:
cd ~ # 进入用户目录
wget https://download.qemu.org/qemu-5.1.0.tar.xz
以防万一,直接安装几个QEMU对应的依赖:
sudo apt-get install pkg-config libglib2.0-dev libpixman-1-dev
解压,进入目录,配置,编译,安装,这一步的时间比较长,请耐心等待
tar xf qemu-5.1.0.tar.xz
cd qemu-5.1.0
./configure --disable-kvm --disable-werror --prefix=/usr/local --target-list="riscv64-softmmu"
make -j4 # 多线程更快
sudo make install # 写入/usr/local目录需要sudo权限
结束之后,因为编译的目标目录都在/usr/local下,因此可以直接在bash下用两个–version来测试是否安装成功:
riscv64-unknown-elf-gcc --version
qemu-system-riscv64 --version
这里出现两个正常打印出的版本信息,就是安装成功了
6.克隆xv6内核代码,编译,QEMU启动
我们的实验在我们的一个仓库上运行,如果你需要跟着MIT的课程完成xv6内核的实验,请从git://g.csail.mit.edu/xv6-labs-2021 这个链接克隆代码,这里介绍的是我们用到的仓库。在Gitee注册账户之后,在Ubuntu环境下使用下面的代码设置全局的用户名和邮箱:
git config --global user.email "you@example.com" # 替换为你Gitee账户的邮箱
git config --global user.name "Your Name" # 替换为你Gitee账户的名字
然后把实验用xv6内核的代码克隆下来
cd ~ # 进入用户目录
git clone https://gitee.com/greenhandzpx/xv6-oslab23-hitsz.git
# 如果你跟着MIT课程的实验,就把上面的链接换成git://g.csail.mit.edu/xv6-labs-2021
然后进入文件夹,切换到util分支,然后用make构建内核,使用qemu启动:
cd xv6-oslab23-hitsz
git checkout util # 这一行用于切换分支
make qemu # 这一行使用Makefile文件的qemu标签构建内核
上述操作全部完成之后,可以看到这样的结果:
但是实际上,make qemu结束之后可能会出现这样的error(这是我截的别的机器上的图):
它提示 ./user/sh.c这个文件当中的第57行有infinite recursion detected,也就是检测到了无线递归,所以这个地方我们要对这一行代码进行一些修改,我们输入
vim user/sh.c
通过vim进入user目录下的sh.c这个文件,找到第57行的void runcmd(struct cmd *cmd) {,然后我们在void前按一下i,看到左下角变成INSERT,然后按回车,在这一行的上方插入这行代码(注意attribute的前后都有两个下划线):
__attribute__((noreturn))
然后这个时候按一下Esc键,然后输入 :wq(还是记得要输入这个冒号!),这样就保存并退出了,这时候再输入make qemu,它就会继续完成项目的构建,然后通过qemu启动xv6内核,然后你就可以看到前面的运行成功的界面了
此时输入ls可以查看所有已经内置于xv6内核中的程序,如cat等基本程序,此时可以用cat README查看xv6内核的README文档
7.GDB远程调试xv6(仅限WSL)
WSL(Windows Subsytem for Linux)在远程连接方面具有得天独厚的优势,我们在命令行输入:
echo "set auto-load safe-path /" >> ~/.gdbinit
expr $(id -u) % 5000 + 25000 # 这一步获取GDB端口号,要记住,一般是26000
cd xv6-oslab23-hitsz
code .
这时候可以直接召唤出本机的VS Code,并且此时这个窗口中已经连接上了WSL的主机,此时我们需要下载Remote-SSH,C/C++,Chinese以及Native Debug等插件,结束后,在VS Code里召唤出终端(左上角点击终端→新建终端,在下面的终端中点击加号→WSL窗口),此时你应该确保当前路径在xv6-oslab23-hitsz当中
然后此时点击VSCode左边的运行和调试,点击创建launch.json,把这个复制进去:
{
"version": "0.2.0",
"configurations": [
{
"type": "gdb",
"request": "attach",
"name": "Attach to gdbserver",
"executable": "${workspaceRoot}/kernel/kernel",
"gdbpath": "gdb-multiarch",
"remote": true,
"target": "127.0.0.1:此前你得到的GDB端口号",
"cwd": "${workspaceRoot}",
"setupCommands": {
"text": "source ${workspaceFolder}/.gdbinit"
}
}
]
}
然后在VSCode的kernel文件夹中找到main.c,在第11行加上断点,再打开xv6-oslab23-hitsz/.gdbinit文件,在target remote 127.0.0.1前面加上# 注释掉
最后,按下F5/点击运行与调试的绿色三角,如果看到刚刚的断点已经成功命中,那么就成功了!