操作系统实践课程实践任务,包括开发环境的准备与交叉编译器、qemu模拟器、gdb调试器等工具的安装与使用。
基于qemu的RISC-V 64 位版本的 Linux的启动。
报告截图的用户名会有变化,因为我创建了多台虚拟机进行实验。
虚拟机搭建见个人总结博文:搭建虚拟机
直接使用官方提供的 GNU工具链和 QEMU 模拟器,执行如下命令在线安装:
sudo apt update
sudo apt install build-essential gcc make perl dkms git gcc-riscv64-unknown-elf gdb-multiarch qemu-system-misc
至此环境准备结束。
GNU交叉编译工具链已安装 riscv64-unknown-elf-gcc
。
riscv64-unknown-elf-gcc --version
尝试编使用riscv64-unknown-elf-gcc
进行编译,报错。
由参考资料errata.pdf
【勘误4-2】可知,错误是正常且不影响课程的。
尝试使用riscv64-linux-gnu-gcc
成功编译。
但是qemu模拟运行却报错。
Invalid ELF image for this architecture
发现默认是Shared object file,在编译的时候加上-no-pie
参数。
riscv64-linux-gnu-gcc -no-pie hello.c
但是重新qemu运行依然报错,思考后认为是编译默认64位(riscv64-unknown-elf-gcc的参数指定在riscv64-linux-gnu-gcc中无效)和qemu模拟32位的冲突。
参照参考文献【5】,重新进行。
编译后file查看确定无误为RISC-V,交叉编译成功。
QEMU 是一套由 (Fabrice Bellard) 编写的以 GPL 许可证分发源码的计算机系统模拟软件,在 GNU/Linux 平台上使用广泛。
在环境准备中已经安装好了qemu,下面检查一下是否成功。
使用如下命令查看qemu:
qemu-system-riscv64 --version
使用参考:学习使用 GDB 调试代码 | Linux 中国
自动化构建管理工具。
os.h
的context结构体存储寄存器状态。
我们的系统仅仅运行在一个核中,要实现多任务需要保存上下文的值(实际上就是寄存器以及程序计数器等重要环境的值)。
工作目录是riscv64-linux
,交叉工具链目录是riscv-gnu-toolchain
。
根据参考文献【5】,以及前文的内容完成交叉工具链的制作。
需要注意参考文献【6】中的所有内容都需要把
riscv64-unknown-linux-gnu-gcc
替换为$WS/install/bin/riscv64-unknown-linux-gnu-gcc
在学习过程中发现就算是按照指导进行使用国内镜像也总是会有问题,在解决的过程中找到了前辈分享的资源riscv-gnu-toolchain,可以免去苦苦等待且可能出问题的子仓库下载内容。
下载源码压缩包并解压。
wget https://download.qemu.org/qemu-5.1.0.tar.xz
tar xvJf qemu-5.1.0.tar.xz
编译并安装。
cd qemu-5.1.0/
./configure --target-list=riscv64-softmmu,riscv64-linux-user --prefix=/opt/qemu
make -j $(nproc)
sudo make install
回到工作目录riscv64-linux,然后下载内核源码并进入linux目录。
检出到5.4版本。
编译和配置。
make ARCH=riscv CROSS_COMPILE=$WS/install/bin/riscv64-unknown-linux-gnu- defconfig
make ARCH=riscv CROSS_COMPILE=$WS/install/bin/riscv64-unknown-linux-gnu- -j $(nproc)
再次强调这里不是
riscv64-unknown-linux-gnu
,而是$WS/install/bin/riscv64-unknown-linux-gnu-
后面也一样。
下载并进入busybox。
git clone https://gitee.com/mirrors/busyboxsource.git
cd busyboxsource/
配置busybox。
CROSS_COMPILE=$WS/install/bin/riscv64-unknown-linux-gnu- make menuconfig
这里遇到bug如下:
fatal error: curses.h: No such file or directory
通过如下命令解决:
sudo apt-get install libncurses5-dev
继续运行
注意这里要把终端窗口大小调大一些,不然会报如下错误:
是我窗口太小不能展示出busybox的GUI界面所致,调大窗口即可。
设置打开配置菜单后进入第一行的 “Settings”,在"Build Options"节中,选中 “Build static binary (no shared libs)”,设置好后退出保存配置。
编译和安装。
CROSS_COMPILE=$WS/install/bin/riscv64-unknown-linux-gnu- make -j $(nproc)
CROSS_COMPILE=$WS/install/bin/riscv64-unknown-linux-gnu- make install
制作一个最小的文件系统。
返回工作目录,输入以下命令。
qemu-img create rootfs.img 1g
mkfs.ext4 rootfs.img
接下来输入如下命令,将_install内的内容拷贝,创建一些文件。
mkdir rootfs
sudo mount -o loop rootfs.img rootfs
cd rootfs
sudo cp -r ../busyboxsource/_install/* .
sudo mkdir proc sys dev etc etc/init.d
然后另外再新建一个最简单的 init 的 RC 文件,具体步骤如下:
cd etc/init.d/
sudo touch rcS
sudo vi rcS
将以下内容粘入文件
#!/bin/sh
mount -t proc none /proc
mount -t sysfs none /sys
/sbin/mdev -s
然后修改 rcS 文件权限,加上可执行权限,这样当 busybox 的init 运行起来后,就能运行这个 /etc/init.d/rcS 脚本。
sudo chmod +x rcS
最后退出 rootfs 目录并卸载文件系统:
sudo umount rootfs
至此,文件系统就制作完成了。
准备工作全部完成,退回工作目录。
运行如下代码:
qemu-system-riscv64 -M virt -m 256M -nographic -kernel linux/arch/riscv/boot/Image -drive file=rootfs.img,format=raw,id=hd0 -device virtio-blk-device,drive=hd0 -append "root=/dev/vda rw console=ttyS0"
根据参考文献【6】
修改参数如下:
qemu-system-riscv64 -M virt -m 256M -nographic -kernel linux/arch/riscv/boot/Image -drive file=rootfs.img,format=raw,id=hd0 -device virtio-blk-device,drive=hd0 -append "root=/dev/vda rw console=ttyS0" -bios default
[1] 课程视频讲解
[2] riscv-operating-system-mooc
[3] csdn [MIT 6.S081] Lab 0: 实验配置, 调试及测试
[4] Running 64- and 32-bit RISC-V Linux on QEMU
[5] 制作交叉工具链 riscv-gnu-toolchain
[6] target-riscv
[7] 在 QEMU 上运行 RISC-V 64 位版本的 Linux