在m1mac上配置mit6.s081的riscv系统环境

 
Category: Tips

写在前面

最近想学一下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 and riscv-gcc-> gcc. I’ve tested the following steps using Homebrew:

  1. Edit the brew formula: brew edit riscv-gnu-toolchain;
  2. 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"
  1. 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)
 {

这样就行了.

参考