1. Ubuntu虚拟机配置实验环境
- 使用Ubuntu20.04,别的版本有可能有问题
- 环境配置大约需要9GiB的空间
1.1 安装RISC-V交叉编译工具
- 克隆RISC-V交叉编译工具的仓库到本地
$ git clone --recursive https://github.com/riscv/riscv-gnu-toolchain
- 下载编译所需的工具包
注意:不是Ubuntu20.04下载可能会有问题
$ sudo apt-get install autoconf automake autotools-dev curl libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo gperf libtool patchutils bc zlib1g-dev libexpat-dev
- 配置并编译工具链
$ cd riscv-gnu-toolchain $ ./configure --prefix=/usr/local $ sudo make $ cd ..
1.2 编译 QEMU 5.1.0
- 下载并且解压QEME 5.1.0资源包
$ wget https://download.qemu.org/qemu-5.1.0.tar.xz $ tar xf qemu-5.1.0.tar.xz
- 为riscv64-softmmu编译QEMU
$ cd qemu-5.1.0 $ ./configure --disable-kvm --disable-werror --prefix=/usr/local --target-list="riscv64-softmmu" $ make $ sudo make install $ cd ..
1.3 测试环境是否配置成功
```Shell
测试riscv64交叉编译工具
$ riscv64-unknown-elf-gcc –version riscv64-unknown-elf-gcc (GCC) 10.1.0 …
- 克隆RISC-V交叉编译工具的仓库到本地
测试qemu工具
$ qemu-system-riscv64 –version QEMU emulator version 5.1.0
#### 2. 运行xv6操作系统
[mit6.S081官网链接](https://pdos.csail.mit.edu/6.S081/2020/labs/util.html)
##### 2.1 下载实验压缩包并切换到util分支
```Shell
$ git clone git://g.csail.mit.edu/xv6-labs-2020
Cloning into 'xv6-labs-2020'...
...
$ cd xv6-labs-2020
$ git checkout util
2.2 编译并且运行xv6
$ 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
$
如果你使用ls
命令,可以看到以下输出:
$ ls
. 1 1 1024
.. 1 1 1024
README 2 2 2059
xargstest.sh 2 3 93
cat 2 4 24256
echo 2 5 23080
forktest 2 6 13272
grep 2 7 27560
init 2 8 23816
kill 2 9 23024
ln 2 10 22880
ls 2 11 26448
mkdir 2 12 23176
rm 2 13 23160
sh 2 14 41976
stressfs 2 15 24016
usertests 2 16 148456
grind 2 17 38144
wc 2 18 25344
zombie 2 19 22408
console 3 20 0
这些都是在系统初始化文件 mkfs
中的命令。
使用 Ctrl + p
可以打印每个进程的信息,如果现在使用可以看到有两个进程:一个是init
,另一个是sh
。
退出系统:Ctrl + a x
3. 开始实验
3.1 加入第一个实验函数sleep
- 自己添加的函数需要添加到
/user
目录下 - 在
Makefile
文件中添加sleep.c
的编译规则
UPROGS=\
_cat\
_cp\
_echo\
_forktest\
_grep\
_init\
_kill\
_ln\
_ls\
_mkdir\
_rm\
_sh\
_wc\
_zombie\
_copy\ # 添加copy.c编译规则
- 重新编译xv6
$ make qemu
3.2 测试分数
- 全部测试
$ make grade
- 测试当前函数
$ ./grade-lab-util sleep $ make GRADEFLAGS=sleep grade
以上两个命令的效果相同。
提示:
如果运行命令 ./grade-lab-util sleep 报 /usr/bin/env: ‘python’: No such file or directory
错误,请使用命令 vim grade-lab-util
,把第一行 python
改为 python3
。
另外:
如果系统没装 python3
,请先安装 sudo apt-get install python3
。
参考:CSDN
3.3 使用git管理分支
# 初始化一个git仓库
$ git init
# 创建一个新分支
$ git branch <new-branch>
# 切换到某个分支
$ git checkout <branch-name>
# 将修改的文件全部添加到缓存区
$ git add .
# 将所有文件提交
$ git commit -m "something to say"
# 查看当前分支的提交记录
$ git log
# 合并分支到当前分支
$ git merge <branch-name>
# 展示某分支最新修改的内容
$ git show <branch-name>
** 注意:**新初始化的分支没有进行任何提交的时候分支不会显示
工作树:
git使用了工作树的概念,工作树是你正在处理的文件的本地副本。当子分支被创建的时候会继承创建子分支时当前分支的文件状态,但是在接下来的提交会和本子分支相关联。可以使用git show <branch-name:filename>
来查看某个分支中某个文件的状态。
$ git checkout master
$ ls
init
$ git checkout test1
$ ls
init test1
$ git checkout -b test2
$ ls
init test1
$ git checkout master
$ git checkout -b test3
$ ls
init
由以上代码可以看出 master
分支中有 init
文件,test1
分支中有 init
和 test1
文件,test2
由 test1
分支检出,而 test3
由 master
分支检出,所以 test2
中包含了 test1
中所有文件的副本, test3
中包含了master 中所有文件的副本。