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

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

目标:Write your own OS in C
作者:ljl2107(学号:hello os)
日期:2023年7月20日

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

目录

简介

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

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

环境准备

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

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

直接使用官方提供的 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

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

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

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

重新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

在这里插入图片描述

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

在这里插入图片描述

编译并安装。

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

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

导出 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)

在这里插入图片描述

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

制作 rootfs

下载并进入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

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

可以看到_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

三、实验内容与要求 1、熟悉windows的编程接口,使用系统调用编程实现将参数1对应文件1.txt和参数2对应文件2.txt的内容合并到参数3对应文件zong.txt中(上传文件名为学号后5位ex0701.c)。 2、使用windows提供的命令将文件1.txt和文件2.txt的内容合并到文件total.txt中 (请将实现的操作命令写入下题批处理文件的第一行)。 3、主管助理小张经常接收公司员工发来的文件,开始为了节省时间,小张将下载的文件都保存在文件夹xiazai中(文件名如图1所示,下载后直接解压即可),这样不便于后期的统计和分类管理,现在领导要求必须为所有员工(90人)每人单独建立一个文件夹(以员工工号命名10201、10202......10290),然后将他们提交的文件分别剪切到各自对应的文件夹中(如图2所示)。于是小张开始为7名员工建立文件夹,再一个一个的去做……同学们想想有没有一种方法能快速完成所要求的操作呢? 请熟悉windows的命令接口,使用windows提供的常用命令copy、md、del等编写一个批处理文件(上传文件名为学号后5位ex0703.bat),实现所要求的功能: 1、启动linux系统或通过windows telnet到linux。 2、用huas用户名和密码123456登入系统中。 3、打开一终端窗口(在linux桌面上单击右键,选择从终端打开)。然后在其中输入以下命令实验。 4、熟悉常用操作命令. 5、编辑如下源代码(实验教材P86 1.进程的创建)并保存 二、实验目的 (1)加深对进程概念的理解,明确进程和程序的区别。 (2)分析进程竞争资源现象,学习解决进程互斥的方法。 (3了解Linux系统中进程通信的基本原理。 三、实验内容与要求 (1)任务一:编写一段程序,使其实现进程的软中断通信。 要求:使用系统调用fork()创建两个子进程,再用系统调用signal()让父进程捕捉键盘上来的中断信号(即按DEL键);当捕捉到中断信号后,父进程用系统调用Kill()向两个子进程发出信号,子进程捕捉到信号后分别输出下列信息后终止: Child Processll is Killed by Parent! Child Processl2 is Killed by Parent! 父进程等待两个子进程终止后,输出如下的信息后终止 Parent Process is Killed! (2)任务二:在上面的程序中增加语句signal (SIGNAL, SIG-IGN)和signal (SIGQUIT, SIG-IGN),观察执行结果,并分析原因。 (3)任务三:进程的管道通信 编制一段程序,实现进程的管道通信。 使用系统调用pipe()建立一条管道线;两个子进程P1和P2分别向管道中写一句话: Child 1 is sending a message! Child 2 is sending a message! 而父进程则从管道中读出来自于两个子进程的信息,显示在屏幕上。 要求父进程先接收子进程P1发来的消息,然后再接收子进程P2发来的消息。 二、实验目的 自行编制模拟程序,通过形象化的状态显示,加深理解进程的概念、进程之间的状态转换及其所带来的PCB内容 、组织的变化,理解进程与其PCB间的一一对应关系。 三、实验内容与要求 1)设计并实现一个模拟进程状态转换及其相应PCB内容、组织结构变化的程序。 2)独立编写、调试程序。进程的数目、进程的状态模型(三状态、五状态、七状态或其它)以及PCB的组织形式可自行选择。 3)合理设计与进程PCB相对应的数据结构。PCB的内容要涵盖进程的基本信息、控制信息、资源需求及现场信息。 4)设计出可视性较好的界面,应能反映出进程状态的变化引起的对应PCB内容、组织结构的变化。 二、实验目的 存储管理的主要功能之一是合理地分配空间。请求页式管理是一种常用的虚拟存储管理技术。本实验的目的是通过请求页式管理中页面置换算法模拟设计,了解虚拟存储技术的特点,掌握请求页式存储管理的页面置换算法。 三、实验内容与要求 通过计算不同算法的命中率比较算法的优劣。同时也考虑了用户内存容量对命中率的影响。页面失效次数为每次访问相应指令时,该指令所对应的页不在内存中的次数。 计算并输出下属算法在不同内存容量下的命中率。  先进先出的算法(FIFO); 最近最少使用算法(LRU) 二、实验目的 死锁会引起计算机工作僵死,因此操作系统中必须防止。本实验的目的在于使用高级语言编写和调试一个系统动态分配资源的简单模拟程序,了解死锁产生的条件和原因,并采用银行家算法有效地防止死锁的发生,以加深对课堂上所讲授的知识的理解。 三、实验内容与要求 设计有n个进程共享m个系统资源的系统,进程可动态的申请和释放资源,系统按各进程的申请动态的分配资源。 系统能显示各个进程申请和释放资源,以及系统动态分配资源的过程,便于用户观察和分析。 四、算法描述(含数据结构定义)或流程图 (一) 数据结构 1. 可利用资源向量Available ,它是一个含有m个元素的数组,其中的每一个元素代表一类可利用的资源的数目,其初始值是系统中所配置的该类全部可用资源数目。其数值随该类资源的分配和回收而动态地改变。如果Available(j)=k,标是系统中现有Rj类资源k个。 2. 最大需求矩阵Max,这是一个n×m的矩阵,它定义了系统中n个进程中的每一个进程对m类资源的最大需求。如果Max(i,j)=k,表示进程i需要Rj类资源的最大数目为k。 3. 分配矩阵Allocation,这是一个n×m的矩阵,它定义了系统中的每类资源当前一分配到每一个进程的资源数。如果Allocation(i,j)=k,表示进程i当前已经分到Rj类资源的数目为k。Allocation i表示进程i的分配向量,有矩阵Allocation的第i行构成。 4. 需求矩阵Need,这是一个n×m的矩阵,用以表示每个进程还需要的各类资源的数目。如果Need(i,j)=k,表示进程i还需要Rj类资源k个,才能完成其任务。Need i表示进程i的需求向量,由矩阵Need的第i行构成。 上述三个矩阵间存在关系:Need(i,j)=Max(i,j)-Allocation(i,j)。 (二) 银行家算法 Request i 是进程Pi 的请求向量。Request i (j)=k表示进程Pi请求分配Rj类资源k个。当Pi发出资源请求后,系统按下述步骤进行检查: 1. 如果Request i ≤Need,则转向步骤2;否则,认为出错,因为它所请求的资源数已超过它当前的最大需求量。 2. 如果Request i ≤Available,则转向步骤3;否则,表示系统中尚无足够的资源满足Pi的申请,Pi必须等待。 3. 系统试探性地把资源分配给进程Pi,并修改下面数据结构中的数值: 二、实验目的 磁盘是高速、大容量、旋转型、可直接存取的存储设备。它作为计算机系统的辅助存储器,担负着繁重的输入输出工作,在现代计算机系统中往往同时会有若干个要求访问磁盘的输入输出要求。系统可采用一种策略,尽可能按最佳次序执行访问磁盘的请求。由于磁盘访问时间主要受寻道时间T的影响,为此需要采用合适的寻道算法,以降低寻道时间。本实验要求模拟设计一个磁盘调度程序,观察调度程序的动态运行过程。通过实验来理解和掌握磁盘调度的职能。 三、实验内容与要求 分别模拟如下磁盘调度算法,对磁盘进行移臂操作:  先来先服务算法  最短寻道优先算法 1. 假设磁盘只有一个盘面,并且磁盘是可移动头磁盘。 2. 磁盘是可供多个进程共享的存储设备,但一个磁盘每个时刻只能为一个进程服务。当有进程在访问某个磁盘时,其它想访问该磁盘的进程必须等待,直到磁盘一次工作结束。当有多个进程提出输入输出请求而处于等待状态时,可用磁盘调度算法从若干个等待访问者中选择一个进程,让它访问磁盘。为此设置“驱动调度”进程。 3. 由于磁盘与处理器是并行工作的,所以当磁盘在为一个进程服务时,占有处理器的其它进程可以提出使用磁盘(这里我们只要求访问磁道),即动态申请访问磁道,为此设置“接受请求”进程。 4. 为了模拟以上两个进程的执行,可以考虑使用随机数来确定二者的允许顺序,参考程序流程图。 5. “接受请求”进程建立一张“进程请求I/O”表,指出等待访问磁盘的进程要求访问的磁道,表的格式如下: 进程名 要求访问的磁道号 6. 磁盘调度的功能是查“请求I/O”表,当有等待访问的进程时,按磁盘调度算法从中选择一个等待访问的进程,按其指定的要求访问磁道。流程图中的“初始化”工作包括:初始化“请求I/O”表,设置当前移臂方向;当前磁道号。并且假设程序运行前“请求I/O”表中已有若干进程(4~8个)申请访问相应磁道。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ljl2107

感谢我能帮助到你

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值