• 操作系统实践课程结课报告


    操作系统实践课程结课报告

    目标:Write your own OS in C
    作者:我也需要被治愈(学号:hello os)
    日期:2023年7月20日

    个人觉得这个过程还是蛮有意思的,初步了解了有关的一些内容顺带复习了操作系统课程,虽然很正常的学完后感到头疼和庞杂,但这太正常了,不是吗?
    诸君共勉

    目录

    文章目录

    • 简介
    • 环境准备
    • 交叉编译器
      • 尝试过程
      • 成功实现
    • qemu模拟器
    • gdb调试器
    • make构造工具
    • 上下文切换代码示例运行
    • 启动RVOS
      • 制作交叉工具链
      • 下载源码
      • 制作内核
      • 制作 rootfs
      • 运行

    简介

    操作系统实践课程实践任务,包括开发环境的准备与交叉编译器、qemu模拟器、gdb调试器等工具的安装与使用。
    基于qemu的RISC-V 64 位版本的 Linux的启动。

    报告截图的用户名会有变化,因为我创建了多台虚拟机进行实验。

    环境准备

    • VMware Workstation 16 Pro
    • 操作系统:ubuntu-20.04.6-desktop-amd64
      在这里插入图片描述

    虚拟机搭建见个人总结博文:搭建虚拟机

    直接使用官方提供的 GNU工具链和 QEMU 模拟器,执行如下命令在线安装:

    sudo apt update
    
    • 1
    sudo apt install build-essential gcc make perl dkms git gcc-riscv64-unknown-elf gdb-multiarch qemu-system-misc
    
    • 1

    至此环境准备结束。

    交叉编译器

    在这里插入图片描述

    尝试过程

    GNU交叉编译工具链已安装 riscv64-unknown-elf-gcc

    riscv64-unknown-elf-gcc --version
    
    • 1

    在这里插入图片描述
    尝试编使用riscv64-unknown-elf-gcc进行编译,报错。
    在这里插入图片描述

    由参考资料errata.pdf【勘误4-2】可知,错误是正常且不影响课程的。
    在这里插入图片描述

    尝试使用riscv64-linux-gnu-gcc成功编译。
    在这里插入图片描述

    但是qemu模拟运行却报错。

    Invalid ELF image for this architecture

    使用file查看文件
    在这里插入图片描述

    发现默认是Shared object file,在编译的时候加上-no-pie参数。

    riscv64-linux-gnu-gcc -no-pie hello.c 
    
    • 1

    重新file查看。
    在这里插入图片描述

    但是重新qemu运行依然报错,思考后认为是编译默认64位(riscv64-unknown-elf-gcc的参数指定在riscv64-linux-gnu-gcc中无效)和qemu模拟32位的冲突。

    成功实现

    参照参考文献【5】,重新进行。
    在这里插入图片描述
    编译后file查看确定无误为RISC-V,交叉编译成功。
    在这里插入图片描述

    qemu模拟器进行模拟,报错按照提示修复即可。
    在这里插入图片描述
    在这里插入图片描述

    可以看到这个目标文件是不能在当前的系统下运行的
    在这里插入图片描述

    最后通过qemu模拟运行,成功!
    在这里插入图片描述

    qemu模拟器

    QEMU 是一套由 (Fabrice Bellard) 编写的以 GPL 许可证分发源码的计算机系统模拟软件,在 GNU/Linux 平台上使用广泛。

    在环境准备中已经安装好了qemu,下面检查一下是否成功。
    使用如下命令查看qemu:

    qemu-system-riscv64 --version
    
    • 1

    在这里插入图片描述

    gdb调试器

    在环境准备中已经安装好了gdb,下面检查一下是否成功。
    在这里插入图片描述

    使用参考:学习使用 GDB 调试代码 | Linux 中国

    make构造工具

    自动化构建管理工具。

    上下文切换代码示例运行

    在这里插入图片描述

    os.h的context结构体存储寄存器状态。
    在这里插入图片描述
    我们的系统仅仅运行在一个核中,要实现多任务需要保存上下文的值(实际上就是寄存器以及程序计数器等重要环境的值)。

    关键函数是(switch_to)
    在这里插入图片描述

    启动RVOS

    工作目录是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
    
    • 1
    • 2

    在这里插入图片描述

    编译并安装。

    cd qemu-5.1.0/
    ./configure --target-list=riscv64-softmmu,riscv64-linux-user --prefix=/opt/qemu
    make -j $(nproc)
    sudo make install
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    导出 qemu 的安装目录并验证安装是否正确。
    在这里插入图片描述

    制作内核

    回到工作目录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)
    
    • 1
    • 2

    在这里插入图片描述

    再次强调这里不是riscv64-unknown-linux-gnu,而是$WS/install/bin/riscv64-unknown-linux-gnu-后面也一样。

    制作 rootfs

    下载并进入busybox。

    git clone https://gitee.com/mirrors/busyboxsource.git
    cd busyboxsource/
    
    • 1
    • 2

    配置busybox。

    CROSS_COMPILE=$WS/install/bin/riscv64-unknown-linux-gnu- make menuconfig
    
    • 1

    这里遇到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
    
    • 1
    • 2

    在这里插入图片描述
    在这里插入图片描述

    可以看到_install目录下生成的内容。
    在这里插入图片描述

    制作一个最小的文件系统。
    返回工作目录,输入以下命令。

    qemu-img create rootfs.img  1g
    mkfs.ext4 rootfs.img
    
    • 1
    • 2

    在这里插入图片描述

    接下来输入如下命令,将_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
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述

    然后另外再新建一个最简单的 init 的 RC 文件,具体步骤如下:

    cd etc/init.d/
    sudo touch rcS
    sudo vi rcS
    
    • 1
    • 2
    • 3

    将以下内容粘入文件

    #!/bin/sh
    mount -t proc none /proc
    mount -t sysfs none /sys
    /sbin/mdev -s
    
    • 1
    • 2
    • 3
    • 4

    然后修改 rcS 文件权限,加上可执行权限,这样当 busybox 的init 运行起来后,就能运行这个 /etc/init.d/rcS 脚本。

    sudo chmod +x rcS
    
    • 1

    最后退出 rootfs 目录并卸载文件系统:

    sudo umount rootfs
    
    • 1

    在这里插入图片描述

    至此,文件系统就制作完成了。

    运行

    准备工作全部完成,退回工作目录。
    运行如下代码:

    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"
    
    • 1

    在这里插入图片描述
    出现问题。

    根据参考文献【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

    成功运行!
    在这里插入图片描述在这里插入图片描述

    参考文献

    [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

  • 相关阅读:
    (10)(10.8) 固件下载
    BGP选路规则
    Valkyrie网络测试仪的使用技巧100例--No.000 目录篇
    【教程】微信公众号文章怎么添加Excel表格附件?
    uniapp对tabbar封装,简单好用
    深入解析LLaMA如何改进Transformer的底层结构
    前端字体压缩(免费简单易上手)
    阿里云服务器通用型规格族20个实例规格性能特点和适用场景汇总
    jQuery基础学习(属性操作、循环、事件冒泡委托、元素节点操作、滚轮事件、函数节流、json、ajax、jsonp与本地存储)
    LCR 027. 回文链表
  • 原文地址:https://blog.csdn.net/m0_63288666/article/details/133611872