第一阶段总结
在第一阶段,我主要进行的工作是学习Rust语言,同时也了解学习了一些RISC-V指令集的知识。
我对Rust的学习主要参考了Rust语言圣经。不过,由于时间问题,我只阅读了其中的知识点部分,还未阅读过实战项目部分。由于之后需要进行系统编程,我也粗略地看了一下Rust 秘典(翻译版本)。
学习这些知识之后,完成该阶段的Rustlings任务比较简单。只有少数几道题涉及的知识点较冷门,查询对应知识点时花费了一些时间。
第二阶段总结
ch0 ~ ch2
这几章的实践内容主要是配置实验环境。按照书上的操作,配置起来比较顺利。为了之后开发更方便,我也完成了vscode通过ssh远程登录虚拟机的配置。
第1、2章的学习内容主要是对特权级切换过程和rcore的结构有一个基本的了解,(和之后相比)我觉得算是较为简单的一章。
ch3
本章需要实现多道程序和分时多任务。这一章对我来说是一个难点,因为任务切换、特权级切换的过程比ch2更加复杂了。好在最后还是大致理解了这一过程。
本章的实验是第一个实验,(和之后相比)算是比较简单的,但因为当时我对系统架构还不甚熟悉,该实验对当时的我来说还是有难度的。
我在任务管理块TaskControlBlock
中增加了记录系统调用次数的字段syscall_times
和记录程序开始时间的字段start_time
。将这两个字段初始化,并分别在任务开始时和进入系统调用时更新这两个字段。之后,我实现了系统调用处理函数sys_task_info
,将需要更新的TaskInfo
指针传递到TASK_MANAGER
内部进行处理,让TASK_MANAGER
根据TCB中新增的字段更新TaskInfo
的相应字段。
ch4
本章学习rcore对于地址空间的实现。在阅读过程中,我对本章内容还有一些不理解之处,之后在开发的过程中也慢慢熟悉了。
从本章开始,需要前向兼容。当时我还不知道git cherry-pick
这个命令,因此只能将上一章的代码复制粘贴过来。同时,我在实现两个新的系统调用的时候,原本想把功能代码都写在系统调用函数内,因此也在函数内获取了系统很多资源的引用。结果,我编写的代码怎么修改也通不过Rust编译器的引用检查和生命周期检查,只能重写。这次,我将和不同数据结构有关的功能代码封装成那些数据结构对应的方法,让系统调用函数去使用这些方法,这才通过了编译。这一经历也让我养成了更好的编码习惯。
我重写了sys_get_time
和sys_task_info
函数,使它们恢复正常功能。为了做到这点,我编写了map_user_va_to_pa
函数,将用户空间的虚拟地址转化为物理地址。通过该函数,我将sys_get_time
和sys_task_info
函数的输入的指针参数进行了地址变换,再完成之前的工作。
我实现了mmap
和munmap
系统调用。它们首先检查输入参数的合法性,再通过TASK_MANAGER
获得当前进程的pcb,进而获得当前进程的用户地址空间。之后,调用我实现的地址空间的map_va_range
和unmap_va_range
方法,完成对应的操作。
ch5
本章学习rcore的进程管理。有了前几章的铺垫,这章我感觉学起来较为轻松。
在本章,我学到并使用了git cherry-pick
命令。由于这一章涉及进程的代码结构变换较大,而我之前修改的代码也有很多涉及进程TCB,因此出现了大量的合并冲突,其中一部分还只能手动解决。我花费了一些时间解决这些冲突,并且一边解决一边尝试编译,看能否正常运行。
我实现了spawn
系统调用,根据目标程序新建子进程,并且维护它和调用进程的父子关系。参考fork
和exec
的代码,该系统调用较容易实现。我实现了stride调度算法,在TCB的inner字段中增加了记录stride调度算法所需的数据项priority
和stride
。增加了设置进程优先级的系统调用set_priority
。最后,重写了TaskManager::fetch
函数,让其每次选取stride
值最小的进程进行调度,并且维护被调度的进程的stride
值。
时间关系,目前只完成了这些实验。在晋级之后,我也会继续对rcore的学习,继续完成实验。例如,我目前阅读完了第6章,准备开始第6章的实验。