Skip to content

Latest commit

 

History

History
247 lines (195 loc) · 10.3 KB

File metadata and controls

247 lines (195 loc) · 10.3 KB

xv6-labs-2020

MIT6.s081 麻省理工2020秋季学期操作系统工程(Operating System Engineering)实验。Windows 下成功编译运行。

🧀 课程资源汇总、课堂笔记、读书笔记:github/PiperLiu/CS-courses-notes/mit6.s081

本仓库来自 git clone git://g.csail.mit.edu/xv6-labs-2020

🧂如何安装

实验基于 xv6 操作系统(简化版 Unix version 6)。实验需要在类 unix 系统(MacOS/Linux)上安装 RISC-V versions of a couple different tools: QEMU 5.1, GDB 8.3, GCC, and Binutils 。官方安装说明在这里

我使用的是 WSL2 (Windows Subsystem for Linux 2)。

🌭首先检查版本
$ cat /etc/debian_version
bullseye/sid

$ cat /proc/version
Linux version 4.19.104-microsoft-standard (oe-user@oe-host) (gcc version 8.2.0 (GCC)) #1 SMP Wed Feb 19 06:37:35 UTC 2020

🍿然后安装工具
$ sudo apt-get update

$ sudo apt-get install git build-essential gdb-multiarch qemu-system-misc gcc-riscv64-linux-gnu binutils-riscv64-linux-gnu
$ sudo apt-get remove qemu-system-misc
$ sudo apt-get install qemu-system-misc=1:4.2-3ubuntu6

🥓如何使用

切换到相应作业分支,然后 make qemu 后 xv6 操作系统就自动运行起来了。

比如:

$ git checkout util
$ make qemu

...编译、执行...

xv6 kernel is booting

hart 2 starting
hart 1 starting
init: starting sh
$ 

此时我们可以输入 ls 命令,发现成功执行。

🥚作业索引

Lab: Xv6 and Unix utilities

Lab: system calls

Lab: page tables

Lab: traps

Lab: xv6 lazy page allocation

Lab: Copy-on-Write Fork for xv6

Lab: Multithreading

Lab: locks

Lab: file system

Lab: mmap

Lab: networking

🍎MAC M1 Pro 安装记录(最终选择 docker )

# 在有了 xcode-select --install 和 homebrew 的基础上

brew tap riscv/riscv
brew install riscv-tools

# 确认安装
brew --prefix
brew --prefix riscv-gnu-toolchain
ls -la "$(brew --prefix riscv-gnu-toolchain)/bin" | head
command -v riscv64-unknown-elf-gcc || echo "NOT IN PATH"
echo "$PATH" | tr ':' '\n' | grep -n "riscv-gnu-toolchain" || true

brew install qemu

# 验证
(base) ➜  PiperLiu riscv64-unknown-elf-gcc --version
riscv64-unknown-elf-gcc (g1b306039a) 15.1.0
Copyright (C) 2025 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

(base) ➜  PiperLiu qemu-system-riscv64 --version
QEMU emulator version 10.2.0
Copyright (c) 2003-2025 Fabrice Bellard and the QEMU Project developers

但是如上并不好用,存在两个问题:

  • Mac 上默认的 CPP 工具链能接受的语法与原项目不相容
  • 即便修正语法使之兼容,使用 make qemu 后编译出来的产物也无法正常运行(会 block 住)

原因应该是 qemu-system-misc 太新: At this moment in time, it seems that the package qemu-system-misc has received an update that breaks its compatibility with our kernel. If you run make qemu and the script appears to hang after 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

语法错误举例:

$ make qemu
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 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
$ 

# 新版本的 GCC(12+)添加了 -Winfinite-recursion 警告,配合 -Werror 就变成了编译错误
--- a/user/primes.c
+++ b/user/primes.c
@@ -11,7 +11,7 @@ const int INT_LEN = sizeof(int);
  * 其他数是第一个数的倍数,过滤;
  * 否者传入管道,给子进程
  */
-void get_prime(int*);
+void get_prime(int*) __attribute__((noreturn));
 
 int
 main(int argc, char *argv[])
diff --git a/user/sh.c b/user/sh.c
index 83dd513..c9ad341 100644
--- a/user/sh.c
+++ b/user/sh.c
@@ -52,6 +52,7 @@ struct backcmd {
 int fork1(void);  // Fork but panics on failure.
 void panic(char*);
 struct cmd *parsecmd(char*);
+void runcmd(struct cmd *cmd) __attribute__((noreturn));
 
 // Execute cmd.  Never returns.
 void

尝试过一些其他的方法,目前只有以下方法很快捷方便。还是选择较老的环境:

docker rm -f xv6-focal xv6-amd64 2>/dev/null || true

# 起一个 arm64 的 focal 容器常驻
# 如果起一个 amd64 的,会因为 Rosetta for Linux 对某些 syscall(比如 282)不支持
# qemu 崩溃 rosetta error: Unimplemented syscall number 282
docker run -d \
  --platform linux/arm64 \
  --name xv6-focal-arm64 \
  --restart unless-stopped \
  -v "$(pwd)":/work \
  -w /work \
  ubuntu:20.04 \
  sleep infinity

# 进入容器
docker exec -it xv6-focal-arm64 bash

# 在容器内
apt-get update
DEBIAN_FRONTEND=noninteractive apt-get install -y \
  git build-essential gdb-multiarch \
  qemu-system-misc gcc-riscv64-linux-gnu binutils-riscv64-linux-gnu \
  python3

# 让 make grade 里用到的 `python` 命令存在
ln -sf /usr/bin/python3 /usr/local/bin/python

# 验证关键版本与可执行文件
root@548928b76f04:/work# qemu-system-riscv64 --version
QEMU emulator version 4.2.1 (Debian 1:4.2-3ubuntu6.30)
Copyright (c) 2003-2019 Fabrice Bellard and the QEMU Project developers
root@548928b76f04:/work# python --version
Python 3.8.10

root@548928b76f04:/work# apt-cache madison qemu-system-misc | head
qemu-system-misc | 1:4.2-3ubuntu6.30 | http://ports.ubuntu.com/ubuntu-ports focal-updates/main arm64 Packages
qemu-system-misc | 1:4.2-3ubuntu6.30 | http://ports.ubuntu.com/ubuntu-ports focal-security/main arm64 Packages
qemu-system-misc | 1:4.2-3ubuntu6 | http://ports.ubuntu.com/ubuntu-ports focal/main arm64 Packages
# 挑一个 1:4.2-3ubuntu6.xx 来装
root@548928b76f04:/work# apt-get install -y qemu-system-misc=1:4.2-3ubuntu6.30