写在前面
最近想学一下OS的一些内容, 斟酌良久, 选择MIT的6.SO81课程(2021), 链接:6.S081 / Fall 2021 (mit.edu).
第一步先从配置Lab环境开始, 由于我的mac是M1芯片, 安装RISCV花了不少时间, 不过还是在强大的开发者帮助下完成了, 下面记录一下. 参考了课程主页的工具链配置部分1.
安装基本工具
首先需要安装包管理工具brew, 这里可以看我之前的文章, 写的相当详细了. 这里直接从brew安装之后说.
brew tap riscv/riscv
brew install riscv-tools # 这步需要的时间很长
brew install qemu
上面的第二步我遇到了一个问题:
When I install riscv-gnu-toolchain latest version with brew, I got an error with it, the error info like this:
==> Installing riscv/riscv/riscv-tools dependency: riscv-gnu-toolchain
==> git submodule update --init --recursive newlib
==> git submodule update --init --recursive riscv-binutils
Last 15 lines from /Users/evans/Library/Logs/Homebrew/riscv-gnu-toolchain/02.git:
2022-08-23 07:34:00 +0000
git
submodule
update
--init
--recursive
riscv-binutils
error: pathspec 'riscv-binutils' did not match any file(s) known to git
With analyse code I found there had changed submodule path of binutils. In old version riscv-gnu-toolchain used riscv-binutils, but in new version removed "riscv-" prefix, so it's failed with brew
查看issue找到了解决方案2.
I’ve check the rename of two submodules
riscv-binutils
->binutils
andriscv-gcc
->gcc
. I’ve tested the following steps using Homebrew:
- Edit the brew formula:
brew edit riscv-gnu-toolchain
;- Rename the two submodules mentioned (remove the
riscv-
prefix):# need to pull in needed submodules (now that they are disabled above) system "git", "submodule", "update", "--init", "--recursive", "newlib" system "git", "submodule", "update", "--init", "--recursive", "binutils" system "git", "submodule", "update", "--init", "--recursive", "gcc"
- Fix the “workaround for M1” paths:
# Workaround for M1 # See https://github.com/riscv/homebrew-riscv/issues/47 system "sed", "-i", ".bak", "s/.*=host-darwin.o$//", "gcc/gcc/config.host" system "sed", "-i", ".bak", "s/.* x-darwin.$//", "gcc/gcc/config.host"
主要就是去掉两个riscv-
前缀, 就OK了.
安装是通过源码编译的, 我的m1上编译 了差不多半小时才完成.
配置
环境变量默认直接就是走的/opt/homebrew/bin/
所以不需要额外添加了. 默认的工具链是:
# M1mac终于有gdb了
riscv64-unknown-elf-addr2line riscv64-unknown-elf-gdb
riscv64-unknown-elf-ar riscv64-unknown-elf-gdb-add-index
riscv64-unknown-elf-as riscv64-unknown-elf-gprof
riscv64-unknown-elf-c++ riscv64-unknown-elf-ld
riscv64-unknown-elf-c++filt riscv64-unknown-elf-ld.bfd
riscv64-unknown-elf-cpp riscv64-unknown-elf-lto-dump
riscv64-unknown-elf-elfedit riscv64-unknown-elf-nm
riscv64-unknown-elf-g++ riscv64-unknown-elf-objcopy
riscv64-unknown-elf-gcc riscv64-unknown-elf-objdump
riscv64-unknown-elf-gcc-12.2.0 riscv64-unknown-elf-ranlib
riscv64-unknown-elf-gcc-ar riscv64-unknown-elf-readelf
riscv64-unknown-elf-gcc-nm riscv64-unknown-elf-run
riscv64-unknown-elf-gcc-ranlib riscv64-unknown-elf-size
riscv64-unknown-elf-gcov riscv64-unknown-elf-strings
riscv64-unknown-elf-gcov-dump riscv64-unknown-elf-strip
riscv64-unknown-elf-gcov-tool
但是当我克隆xv6源码并运行make qemu
之后, 又报了一个错, 如下:
riscv64-linux-gnu-gcc -Wall -Werror -O -fno-omit-frame-pointer -ggdb -MD -mcmodel=medany -ffreestanding -fno-common -nostdlib -mno-relax -I. -fno-stack-protector -fno-pie -no-pie -c -o user/sh.o user/sh.c
user/sh.c: In function 'runcmd':
user/sh.c:58:1: error: infinite recursion detected [-Werror=infinite-recursion]
58 | runcmd(struct cmd *cmd)
| ^~~~~~
user/sh.c:89:5: note: recursive call
89 | runcmd(rcmd->cmd);
| ^~~~~~~~~~~~~~~~~
user/sh.c:109:7: note: recursive call
109 | runcmd(pcmd->left);
| ^~~~~~~~~~~~~~~~~~
user/sh.c:116:7: note: recursive call
116 | runcmd(pcmd->right);
| ^~~~~~~~~~~~~~~~~~~
user/sh.c:95:7: note: recursive call
95 | runcmd(lcmd->left);
| ^~~~~~~~~~~~~~~~~~
user/sh.c:97:5: note: recursive call
97 | runcmd(lcmd->right);
| ^~~~~~~~~~~~~~~~~~~
user/sh.c:127:7: note: recursive call
127 | runcmd(bcmd->cmd);
| ^~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors
make: *** [<builtin>: user/sh.o] Error 1
这个错是递归调用导致的, 第一种解决方案是通过修改Makefile
:
CFLAGS = -Wall -Werror -O -fno-omit-frame-pointer -ggdb -Wno-error=infinite-recursion
最后加上不报递归调用的错的选项就OK, 但是这里倾向于第二种方法3.
在xv6-labs-2021/user/sh.c
文件中, runcmd
函数上面添加设置特殊属性的宏:
__attribute__((noreturn))
void
runcmd(struct cmd *cmd)
{
这样就行了.