0%

2022开源操作系统训练营第二阶段总结-刘逸珑

操作系统第二阶段结营

选题方向总体设想

通过一种实现模块的方式,对于各个不同的章节进行实现,在对于其他章节的学习的时候,尽可能的尝试不对于其他章节进行修改,以尽可能的保证在不同章节中的学习中,各个章节中的内容可以尽可能的进行复用,不至于在对于某个章节中的内容进行修改之后,需要对于其他模块(不同章节中实现的内容)进行大幅度的修改

杨工提供的简单的设计说明

workspace中的crate进行了如下的几个分类

  • 程序

    • 内核
      能编译出内核。显然教程每章应该编译出一个内核,但所有章节都在一个 bin crate,或者每章/实验都在独立的 bin crate,或者分成一些组?还不确定。
    • 测试样例
      教程中出现不编译出内核的 bin crate 的唯一理由就是需要对内核进行测试。
      • 内核测试样例(对于组件功能进行测试)
        运行在内核态,测试某些组件,或者说是不能带用户程序的特殊内核(不一定最后会有)。
      • 用户测试样例
        能运行在某些章节内核中的用户程序。
    • 工具
      运行在开发环境的应用程序,比如 xtask。
    • 规范
      根据某种成文规范实现的库,类似 riscv。规范库可能是接口库也可能是实现库,以正确反映规范文本为佳。这类库应该在自述文件中给出依据的规范文本(的链接),尤其是要指定规范版本以及当前实现的完整性。

      这类库具有最大的迁移性,仅取决于其参照的规范文本的迁移性。如果完善到一定程度,可以独立到专用仓库并发布。

    • 接口

这种库用于规范实现,方便在不同内核之间迁移。一旦最终决定有多个编译出内核的 bin crate,必然存在使实现在它们之间迁移的接口库。

  • 实现
    普通的 lib crate。如果对同一功能可能有多种实现,可能使用 cfg feature 或抽象出接口库。

我在本方向的总体设想

碎碎念:想要尝试从某种程度上来讲对于SCHEDULEutil等各个不同的模块进行实现,然后从实现多个可复用的crate的情况下,实现从多个不同的crate中抽象出某种程度上的规范(这个地方其实是基于我当前对于rust语言trait相关操作的了解其实相对来说没有那么的高而做出的【这个是初期计划】,还尝试过一些其他方式,比如说对于之前各个章节中各个模块之间的链接关系进行分析最初的想法 - 可视化分析 1, 初期的想法 - 可视化分析 2第二期想法 - 原rCore架构分析,也有简单的的完成了架构分析之后,尝试直接抽象出规范第二期想法 - 直接抽象出规范,但是最后我改变了原先的先设计完成对应的规范,之后再对于原先的各个crate进行实现的设想,发现可能一边实现,一边完成对应的操作,相对来说比较适合我)

正文:想尝试最终实现的结果有点类似于,我们专门提供一个类似于杨工和原rCore中的初始化函数类似的main.rs文件,在文件中初始化所有必要的模块,而这些我们所需要以extern crate将对应的crate置为这个我们设置的config crate的子模块,那些需要引入这些模块的模块,都从这个config crate下属的对应模块要求服务(然后我尝试将完成同样功能的几个不同的模块之间实现的功能进行规范尽可能做到同级可替代使用

目前有关于分级的设想图:

分级设想图

目前的实现结果

基本上可以完成前两个章节的复用,但是当前存在一部分的问题还没有解决【1】,同时因为我相对来说基础较差,基本上只局限于学校课程所通过的理论方向学习,再加上之前有段时间,一直有一个由output::log引发的trap死循环【2】,卡住进度快三周的时间,也没有解决这个对应的问题,最后也只能跳过这个问题,并直接在println宏中内置对应的彩色输出字段,全面在第三章中弃用与output::log相关的内容来跳过这个问题,可能需要继续延长第二阶段的时间,才可能以一个相对更好的方案呈现最终的结果。

当前可以相对较好的完成前三个章节(我基本采用了杨工提供的代码框架,通过xtask对于workspace和各个不同的workspace的链接进行区分),在**当前的设想有点类似于将原先各个不同章节存在区别的初始化(main.py)文件进行复用,然后我们可以对于config cratecargo.toml文件进行修改,进而对于整个操作系统进行一个简单的逻辑变换。

【1】当前发现但是还没有解决的问题

  • 【2】在chapter 3的程序没法完成之后,尝试过很多方法,对于这个部分的内容进行实现,包括完成了几个超过百分之90复用rCore代码的分支,但是都没有办法解决问题, 请教了杨工之后,推荐使用gdb进行汇编单步调试,从而找到问题,更进一步的解决问题,在学习了几天,尝试了很多调试的方案(其他同学提供的vscode下,等。)后面还在杨工的简单指导下学习了最基础的gdb单步调试方案, 但是经过几周的gdb,之后一直没有很好的解决这个对应的问题,期间也与鹿敏宽同学沟通过,他也看了下我的代码,但是也没有发现任何的问题。
    其中有一次,我尝试以一个相对较大的粒度来进行调试(就是不使用si进行汇编单步调试),然后发现问题实际上集中在我第一次进入trap的处理代码的时候,其中的有关于output::log的使用,会导致无尽的trap,使之陷入无限的死循环,而没法从死循环中出来,进而导致我一直单步汇编调试的时候代码都可以正常运行,不是在某个状态之后qemu直接退出或者其他情况。
    最后,由于出现问题的时候状态太过于奇怪,机器实际执行的代码与其所呈现的汇编代码不一致,实在是超出了我的认知范围,询问杨工之后,同样没有得到一个相对较好的hints或其他的东西,遂只能无奈放弃相关的内容,并在对应的SCHEDULE中删除所有有关于output::log的使用,并且人工替换成为有颜色的输出语句,程序可以正常运行。
  • 在进行复用代码的时候存在一定的问题,比如说通过cargo qemu --ch 2 + config处设定当前使用的SCHEDULE模块对应的是batch是可以正常运行的,但是如果使用cargo qemu --ch 3则会无法正常运行,目前认为应该与我根据杨工在xtask中完成的对应汇编符号导入相关的错误,就比如说我尝试链接到里面去的trap.S 文件在SCHEDULE::batch and SCHEDULE::time_sharting两个模块之中存在一些细微的差别(其中一个会多出一行换栈的汇编代码)但是因为在当前【我尝试基于对于cargo qemu --ch ?中的参数,进行分析,然后再根据这个分析的结果将不同的汇编代码链接到程序里面,但是在我们使用相同的模块对于不同的章节进行测试的时候就会出现问题,比如说在使用ch3 + SCHEDULE::batch操作的时候可能因为批处理需要额外的换栈,但在链接的时候由于我们是基于选择的章节实现的链接文件的加载,因此链接进去的汇编代码实际上不是我们想要的。
    虽然,对于这个问题我认为有别的,相对更加简单地解决方案,但是考虑到后面的跳板页的存在,实际上在这个地方采用一些手段跳过这个问题并不会从根本上解决问题,可能还需要探索其他解决方法,比如说将对应的汇编代码与SCHEDULE等进行绑定等。

有关于本次训练营中导师和助教的建议

  • 可能会不会第二阶段也安排个集中性学习会更好?感觉本次第二阶段的学习真的很“懵”,不像是第一阶段的那种,我还有一条具体的学习路径,有点找不到路子下手的感觉,而且导师这边好像也不太清楚大概怎么带的样子…
  • 如果说第二阶段可能是尝试让我们以一种参与开源项目的方式来参加的话,可能还得专门搞一次,或者在文档中写一点与之相关的内容我感觉相对来说比较好…
  • 助教所录制的那个视频很好的解决了我对于框架相对来说理解的还是不太明确的效果,会有一种从头带你走的感觉,这个和我之前在日志中写道的相关内容有点类似,就是最后给你捋一遍,你完成的各个部分大致上起到的作用是怎样的,各个组件又是怎么工作的。

其他资料

日志

第一阶段每日进度记录

仓库-分支尚未整理完成

乱七八糟的一些与本次训练营相关的文档