前言

在做过各种语言的项目,对网站架构和职业要求有一个基础认知后,我认为要在卷翻天的职场立足,在了解并能使用前沿技术的同时还得打好计算机基础,所以痛下决心重拾大二摸鱼过去的OS实验。

2018年及以前MIT6.828是MIT的本科生OS课程,2019开始这门课被拆成了6.S081和6.828,分别成为本科生和研究生的OS课程。6.S081的实验由原来的5个拆成了10个,总体难度降低,更加易于基础并不牢固的学生学习。

我将记录2021年课程的实验全过程,下文是运行环境以及调试环境搭建的记录,着重记录如何使用CLion进行远程开发以及远程调试,这在网上很难找到相应资料。

非常佩服能使用原始gdb进行调试的人,已经是一个离不开ide的快速跳转,自动补全,集成调试的废物了。

课程链接:6.S081 / Fall 2021 (mit.edu)

什么是Xv6和RISC-V?

本课程用来教学和演示的操作系统是基于RISC-V指令集架构的Xv6操作系统,但不是一开始就如此。

本课程的前身6.828最开始使用的是Unix V6(简称V6,基于PDP-11硬件体系和旧式C语言开发)作为教学用OS,而在实验环节,学生们主要是在x86架构的CPU上实现一个称为Jos的“外核”架构(exokernel)的操作系统

很多学生怀疑使用V6这样一个30多年前的,使用旧式C语言(比K&R C还要旧)开发的,并且在过时的PDP-11硬件上运行的系统是否合适。而且学生们还要苦于同时学习PDP-11和Intel x86两种不同架构的底层差别。于是在2006年夏天,课程的老师们决定以V6为基础,使用ANSI C写一个新的在Intel x86多处理器计算机上的系统,也就是Xv6,来代替V6。

从2019年开始,新课程6.S081使用精简指令集RISC-V替代了原有的复杂指令集x86来开发Xv6。

总的来说,RISC-V和x86都是CPU的指令集架构,Xv6和Windows、Linux、MacOS等都是运用这些指令集架构来管理硬件的操作系统

安装Linux虚拟机以及必要工具下载

课程的文档里有各个平台的安装教程,本文以VMware Workstation Pro 16中安装Ubuntu20.04.4 Server作为基础环境。

环境配置指引:6.S081 / Fall 2021 (mit.edu)

安装虚拟机可以在百度上找到很多教程,这里不再赘述,仅放出下载链接

我下载的Ubuntu是Server版,只有命令行没有桌面,更喜爱桌面版可以自行下载。

安装完成并启动虚拟机后输入以下命令下载必要工具,主要是c/c++编译工具集,riscv64架构的gnu工具集,qemu虚拟机,git,适用于riscv64架构的gdb。

sudo apt-get install git build-essential gdb-multiarch qemu-system-misc gcc-riscv64-linux-gnu binutils-riscv64-linux-gnu 

直接下载可能会过于缓慢,如果太慢了请先替换apt源为国内源(请尽量用较新的源)。这里使用的是阿里源和清华源,网上教程有很多,以下是我使用的源,用它替换掉*/etc/apt/source.list*中的内容后输入apt-get update就行了。

#添加阿里源
deb http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse
#添加清华源
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-updates main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-updates main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-backports main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-backports main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-security main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-security main restricted universe multiverse

下载Xv6的git仓库

在用户文件夹下输入以下命令下载课程的Xv6源码,注意不要下载Xv6的官方源码而是下载课程改动过的源码,对改动内容感兴趣的话可以使用git log查看改动内容。

git clone git://g.csail.mit.edu/xv6-labs-2021

下载速度可能很缓慢,可以直接从我的git仓库fork一份或直接clone。

仓库链接:foliet/MIT-6.s081 (github.com)

我仓库my+实验名的分支是我自己完成后代码,ricsv分支是Xv6的源码,其他十个分支是对应lab的分支。

git clone git@github.com:Foliet/MIT-6.s081.git #ssh
git clone https://github.com/Foliet/MIT-6.s081.git #https

先进入文件夹内,然后输入以下两条命令。

git checkout util
make qemu

看到如下输出即为启动成功,一切顺利,否则按照课程原文说明逐个工具检查是否下载成功。

riscv64-unknown-elf-gcc    -c -o kernel/entry.o kernel/entry.S
riscv64-unknown-elf-gcc -Wall -Werror -O -fno-omit-frame-pointer -ggdb -DSOL_UTIL -MD -mcmodel=medany -ffreestanding -fno-common -nostdlib -mno-relax -I. -fno-stack-protector -fno-pie -no-pie   -c -o kernel/start.o kernel/start.c
...  
riscv64-unknown-elf-ld -z max-page-size=4096 -N -e main -Ttext 0 -o user/_zombie user/zombie.o user/ulib.o user/usys.o user/printf.o user/umalloc.o
riscv64-unknown-elf-objdump -S user/_zombie > user/zombie.asm
riscv64-unknown-elf-objdump -t user/_zombie | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$/d' > user/zombie.sym
mkfs/mkfs fs.img README  user/xargstest.sh 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 
nmeta 46 (boot, super, log blocks 30 inode blocks 13, bitmap blocks 1) blocks 954 total 1000
balloc: first 591 blocks have been allocated
balloc: write bitmap block at sector 45
qemu-system-riscv64 -machine virt -bios none -kernel kernel/kernel -m 128M -smp 3 -nographic -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 2 starting
hart 1 starting
init: starting sh
$ 

配置Ubuntu的ssh服务器

输入sudo su进入root用户模式,然后输入passwd为root用户设置一个密码。

输入ls /etc/ssh命令查看是否有sshd_config这个文件,如果没有则输入apt-get install openssh-server下载。

sshd_config中的PermitRootLogin的#号去掉,并将值改为yes。

输入service ssh restart重启ssh服务。(如果没设置开机自动启动,那么每次开机都要重启ssh服务

完成后在物理机上打开一个shell,输入以下命令尝试连接虚拟机。

ssh root@{你的虚拟机ip}
ssh root@192.168.126.128 # 比如这样

如果不成功请转向百度找问题,搜索**“以root用户连接ssh服务器”**应该能找到很多教程。

在CLion上连接虚拟机

CLion是jetbrains公司面向c/c++的ide,通过学生优惠可以免费获取全家桶的一年通行证,并且在校期间可以无限续,只需要有edu后缀的邮箱就行了

Clion下载地址:CLion:JetBrains 出品的 C 和 C++ 跨平台 IDE

学生优惠链接:Free Educational Licenses - Community Support (jetbrains.com)

配置工具链

新建一个项目,打开设置,选择构建、执行、部署,选择工具链,点上方加号➕添加一个远程主机,添加一个ssh凭据并手动输入gdb-multiarch的路径来替代默认gdb(原始gdb不能识别riscv的指令集)。

image-20220329105815490

我这里是下了cmake,不下cmake也没关系,只需要管凭据调试器

配置部署服务器

点击上方工具,选择部署,点击配置,填好映射路径。

image-20220329130436272

然后依次点工具部署浏览远程主机,就可以管理虚拟机的文件了,在这里可以很方便的直接管理虚拟机文件。

删除项目内初始的文件(如果有的话),右键项目文件夹,点击部署,然后下载虚拟机里的文件。

配置Makefile项目

打开设置,将构建目标设置为qemu-gdb

image-20220402152641258

*如果设置里显示未检测到Makefile项目就删掉项目文件夹里的.idea*文件夹,然后重新打开项目。**之前的设置会被初始化,需要重新设置一下。

设置完了之后打开Makefile文件,点右上角按钮重新加载项目。

image-20220402152934792

此时索引就建立完毕了,可以自动补全和ctrl+B来快速跳转了。

添加调试配置

在右上角打开运行/调试配置,添加一个远程调试的配置。

image-20220329124021990

课程内的gdb服务器默认使用25000端口。

执行make后会对内核程序和和每个用户程序各生成一个符号文件,内核的符号文件就叫kernel,用户程序的符号文件为_{程序名},例如ls的符号文件为*_ls*。

设置.gdbinit

在*/root文件夹下创建一个名为.gdbinit*的文件

向里面填入如下内容

set confirm off
set architecture riscv:rv64
file kernel/kernel
add-symbol-file user/_ls
set disassemble-next-line auto
set riscv use-compressed-breakpoints yes

这里是调试ls,如果要调试自己写的程序,比如说myproc,就添加一行add-symbol-file user/_myproc

启动调试服务器

在虚拟机的Xv6文件夹下输入make qemu-gdb来启动gdb服务器,如遇到错误可以尝试make clean来清除之前make生成的文件,shell输出以下内容即为开启成功。

*** Now run 'gdb' in another window.
qemu-system-riscv64 -machine virt -bios none -kernel kernel/kernel -m 128M -smp 3 -nographic -drive file=fs.img,if=none,format=raw,id=x0 -device virtio-blk-device,drive=x0,bus=virtio-mmio-bus.0 -S -gdb tcp::25000

如果显示25000端口已被占用或者文件fs.img被占用,应该是上一次运行没有正确退出,请自行百度查找如何根据占用端口或者文件获取pid,然后kill掉,这里建议使用lsof。

  • apt-get install lsof安装lsof。
  • lsof fs.imglsof -i:25000查询进程。

开始调试

点击CLion右上角调试按钮开始调试ls程序,下方会显示连接成功,然后回到shell会发现可以输入命令了,此时我输入ls grep,成功触发断点。

image-20220329131621170

Xv6和CLion相关

  • Xv6没有实现ps程序,要列出当前进程可以在Xv6的终端里中输入ctrl+p,关闭Xv6先按ctrl+a再按x
  • 调试Xv6时发生读取空指针,缓冲区溢出等错误时CLion不会报错,但是会导致调试异常,当系统中断,跳转到spinlock.c等文件内时需要格外注意。
  • 在CLion内可以用ctrl+alt+h来查看一个函数被哪些函数调用了。
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐