新学期伊始,华中科技大学团队在头歌重磅推出《基于RISCV的操作系统实验》,以此作为高校计算机专业课程《操作系统原理》的配套实验,方便即将开始操作系统学习和想要通过实操巩固理论知识的各高校同学使用,同时支持各校老师采用本套实验进行辅助教学!
本套实验课程基于RISC-V的代理内核(ProxyKernel),其中在本套实验开发和设计的代理内核称为PKE(ProxyKernel forEducation),本实验可以作为《操作系统原理》课程的课程实验以及课程设计内容。课程实验的内容需要学习《操作系统原理》课程的读者独立完成,课程设计的内容则鼓励有条件的读者多人合作完成。基于对各层次学生水平的考量,实验组织结构按照基础部分和挑战部分进行划分,基础部分又依照操作系统的中断、内存管理、进程三个概念进一步划分,循序渐进引导学生建立关于操作系统内核核心知识的认知体系。在开始本实验前,学员需具备基本的计算机组成原理、汇编语言、C语言知识,以及《计算机系统基础》课程的学习经历。同时,本实验课程的指导文档和源码已开源于Trustie平台。
操作系统的本质,是介于硬件和用户软件(应用)之间的一个大型软件系统,通过对硬件的包装来支撑应用的运行。这一点,在代理内核(ProxyKernel)上体现得尤为明显:它的作用是为应用提供最基本的操作系统支撑,使其能够在裸机(本实验中采用的是Spike模拟器)上运行。正是由于这一特点,代理内核可以看成是操作系统的一个极小子集。在采用代理内核的场景下,计算机的软硬件界限以及代理内核的地位如下图所示:
在本套实验中,华中科技大学团队选择的“裸机”是一个基于精简指令集(RISC)的RISC-V计算机,该计算机所支撑的指令集为RV64G(支持RISC-V的通用标量指令集以及浮点等诸多扩展)。他们在实验中采用了Spike模拟器来模拟RISC-V计算机的行为,其中Spike模拟器是RISC-V生态中重要的硬件模拟器,它通过软件的办法忠实地“复现”了硬件的行为。相较于在真正的物理机器上开发操作系统,采用模拟器开发操作系统实验具有环境搭载方便,便于调试等优点。
本实验所采取的代理内核方案避免了完整内核方案设计上的很多缺点,因为代理内核的存在“天生”就是为在硬件(模拟器)上支撑应用,而设计的最小化的操作系统内核,可以根据应用的复杂度的不同,调整自身的复杂度:例如,如果只是为了支撑Helloworld!程序,它就只需要加载、系统调用支持即可,无需进程调度、设备、文件,甚至虚拟存储等内容。在支撑的应用非常复杂的情况下(例如,一个多线程的网络媒体服务器),代理内核将约等于一个完整的操作系统内核。从学习操作系统知识的角度来看,代理内核的这些特点更有利于学员站在应用的角度来审视操作系统对硬件的包装和为应用所做的支撑,从而更好地理解从原理课程所学到的知识。
PKE实验由3组基础实验以及挑战实验组成,两部分实验的基本内容和要求如下:
对于基础实验而言,第一组基础实验重点涉及系统调用、异常和外部中断的知识;第二组基础实验重点涉及主存管理方面的知识;第三组实验重点涉及进程管理方面的知识。
对于挑战实验而言,每一组实验的挑战实验都可以理解为在该组实验上的挑战性内容,只给出题目(应用程序)和预期的效果(需要做到的目标)。这一部分实验指导文档只给出大的方向,需要学生(读者)查阅和理解较多课外内容。
基础实验部分:
Lab1_1:系统调用
在PKE操作系统内核中完善系统调用,实现应用程序的屏幕打印功能。
Lab1_2:异常处理
在PKE操作系统内核中完善异常处理,实现应用程序中非法指令的捕捉。
Lab1_3:外部中断
在PKE操作系统内核中完善时钟中断的处理,实现时钟中断信息的打印。
Lab2_1:虚实地址转换
在PKE操作系统内核中完善页表管理,实现应用程序的装载和虚实地址映射。
Lab2_2:简单内存分配和回收
在PKE操作系统内核中完善简单堆的管理,实现应用程序中的简单内存分配和回收。
Lab2_3:缺页异常
在PKE操作系统内核中完善栈缺页异常处理,满足应用程序在执行递归时的栈内存空间需求。
Lab3_1:进程创建
在PKE操作系统内核中完善进程创建支持,满足应用程序所创建的子进程的执行。
Lab3_2:进程yield
在PKE操作系统内核中完善进程释放处理器的支持,使得应用程序中的父子进程交替执行。
Lab3_3:循环轮转调度
在PKE操作系统内核中完善循环轮转调度支持,使得应用程序中的父子进程用完给自时间片后交替执行。
挑战实验部分:
Lab1_challenge1:打印用户程序调用栈
基于Lab1_3的第一组实验的第一个挑战实验,要求设计系统调用,应用程序通过调用该系统调用打印自己的函数调用栈。
Lab1_challenge2:打印异常代码行
基于Lab1_3的第一组实验的第二个挑战实验,要求操作系统截获异常指令的同时能够打印出现异常的代码行的行号。
Lab2_challenge1:复杂缺页异常
基于Lab2_3的第二组实验的第一个挑战实验,要求处理更加复杂的缺页异常,区分合法与非法的缺页异常。
Lab2_challenge2:堆空间管理
基于Lab2_3的第二组实验的第二个挑战实验,要求对堆(heap)进行更精细化的管理。
Lab3_challenge1:进程等待和数据段复制
基于Lab2_3的第三组实验的第一个挑战实验,要求实现进程数据段的复制,同时实现进程的等待(wait)功能。
Lab3_challenge2:实现信号量
基于Lab2_3的第三组实验的第二个挑战实验,要求实现信号量完成进程的同步执行。
头歌平台为每个实验都设置了一个单独的代码仓库,学员在每个实验完成后,需自行记录(采用如notepad++这样的工具软件)自己在本实验所做的改动,并在切换到下一个实验时,将自己在之前实验中的改动填到之前对应的文件中。例如,如果从Lab1_1切换到Lab1_2,则需要在正式开始Lab1_2前,将自己在Lab1_1中所作的修改填写到之前在Lab1_1中所修改的文件。使用Git直接clone的学员可以自动继承代码。
同时,华中科技大学团队在设计和部署本套实验时,针对高校《操作系统原理》课堂的实验安排分为课内设计和课程设计两部分的经验,给出以下两套教学方案:
方案一(学生其他课程负担较重,或不希望实验太难的情况)
课内实验包括所有的基础实验;
课程设计学生可在每组实验中,选择(学生自选)一个挑战实验。
对于课内实验的建议是:每个基础实验=30分,每组实验总分90分;3组实验取平均分(总分仍然是90)后,总分加上实验报告的10分,等于课内实验的总分数;对于课程设计的建议是:每个挑战实验=30分,3个挑战实验总分求和(总分90),最后加上实验报告的10分,等于课程设计的总分数。
方案二(学生平均能力较强,且希望实验分数有区分度的情况)
课内实验包括所有的基础实验,外加基础实验的1个挑战实验;
课程设计学生可在每组实验中,选择之前未完成的一个挑战实验。
对于课内实验的建议是:每个基础实验=20分,外加一个挑战实验,每组实验总分是3*20+30=90分;3组实验取平均分(总分仍然是90)后,总分加上实验报告的10分,等于课内实验的总分数;对于课程设计的建议是:每个挑战实验=30分,3个挑战实验总分求和(总分90),最后加上实验报告的10分,等于课程设计的总分数。
邵志远
华中科技大学教授、博士。主要从事计算机体系结构、操作系统、FPGA、并行计算等领域的研究。主持了湖北省自然科学基金、国家自然科学基金、湖北省科技创新重大专项在内的多个省级和国家项目。参与973计划、国家自然科学基金重大研究计划、国家自然科学基金重点项目等多项国家项目。已在VEE、FPGA、DASFAA等重要学术会议和期刊上发表学术论文近50篇。获得国家发明专利10余项。获得湖北省科技进步一等奖一项。担任了多个国际学术会议的程序委员会、程序委员会主席等职务。现为IEEE会员、中国计算机学会会员。