0%

2025OS训练营三阶段记录

2025OS训练营三阶段记录

4.7-4.8

这两天看了石磊老师的unikernel讲解视频,完成了彩色print和hashmap的任务。

unikernel我是第一次听说,用组件化的方式来实现操作系统,可以对应用定制轻量化的运行环境,相当于操作系统与应用一体,比较适合嵌入式和轻量虚拟化场景。arceos就不像rcore那样是面向教学的了,而是更偏向于实际应用,我查看了toml,操作系统的组件几乎都是依赖导入,刚开始有些搞不清楚这些包的具体用途。

彩色print的实现很简单,在格式化前加入蓝色字符标注即可实现。

hashmap的实现我一开始考虑的是nostd环境是否还需要我来实现对内存分配器,但是后来仔细看过arceos里有实现默认的对内存分配。我的实现内存分配依赖的vec,用vec作为hashmap的底层数据结构,实现起来相对容易,对于通过测例来说还是足够的。

4.9-4.12

这几天在琢磨lab1的挑战题,不愧是挑战题,花了目前最久的时间。题目规范很好,只需要实现规定的部分就可以。内容是要实现一个字节内存分配器来让这个测试达到最大迭代次数。这个测试用例是重点,他是循环分配32+i到2的14次方+i的内存,这个i就是迭代次数,每次迭代会把每一轮偶数次数的分配空间给释放掉,所以每次都有一部分内存不会被释放,即这个挑战有理论最大值。用例的分配用的是vec,vec根据rust的实现每次分配在空间不够时都是要扩容当前一倍的空间的。挑战的分数是i的次数要大于170,因为170是算法tlsf的结果。我对tlsf、buddy算法的实现都手动实现测试了一遍,逐步理清了我的实现思路。

每次分配的偶数情况都会被释放,那直接对偶数情况的内存分配给固定的内存池,比如32 index为0,那分配32+Max的内存池,这个max就是最大i值,中修改max来得到i最大值。对于奇数的情况我使用了最简单的线性分配方法,应为当时想的是每次技术分配的都不会释放,所以不会有间隙,其实不是。这个探索的过程我发现分配的大小没有按照我的想法分配到对应的位置,于是我就打印了每次分配的内存的大小,我发现有几个固定值96,192,386这些数字不符合每次请求的内存大小,猜测应该是对其的要求分配的。所以对这个情况进行处理,直接计数进行跳过。但是效果到64又出现问题,分析发现32涨到96,与固定值96的分配打乱了奇偶计数的顺序,所以对全局分配96的大小进行计数,同样跳过一个固定位次的96分配。同理128在涨到192时也会触发,32在涨到192又会触发。对这些情况都做处理,得到了189的分数,折腾了三天,也总算有个结果,即便我知道这不是最佳答案。

其实问题在于我认为奇数的分配是没有空隙的,其实vec的分配策略,扩容的空间都是浪费了,如果要提升,就要在奇数合并块时,通过某种策略找出未使用的扩容区域,就可以真做到最大限度利用空间,达到无空隙。

这个题目刚开始觉得是个算法题,但其实也让我对内存分配的理解更加的深入。

4.13

今天实现的是bump内存分配策略,同时兼顾页分配和字节分配,通过上次挑战题的考验,这道题相当简单了。而且题目要求也很低,我的实现就是对分配器维护一个左右标签记录已经分配的区域,左为字节分配器的使用位置,右为页面分配器的使用位置。字节分配采用线性分配,每次分配查看左标签内还有没有空余,没有就移动左标签扩容。释放只处理与左标签邻近的地址,将左标签剪去分配的内存大小。右标签则是每次分配页面大小,维护是扩容则减,释放则加。

其实对与这道题的测试用例很松,维护好左右分配标签就可以过。

4.14

今天实现了rename,其实有个最简单的方法就是拷贝删除用来重新创建该文件。

正规做法需要先改下依赖的路径为本地,再将rename实现,arceos的文件系统依赖于虚拟文件系统,根据它的结构找到mata文件即可修改文件名。

4.15

mmap操作需要先理解静态分配,其实很简单,我们平时用到的动态分配就是请求了就立即分配内存空间给用户,静态则是在请求时返回成功,再用到时访问内存会触发pagefault,这个时候再分配内存。mmap需要做到文件映射,本来文件读入内存需要先经过内核空间再到用户空间,mmap在静态分配地址后,手动映射到用户空间,再将文件直接读取到这个物理地址,实现了无拷贝操作。

实现时检查参数有效性,转换传进来的flags格式,获取当前任务的地址空间即可转换给定的虚拟地址为物理地址,使用mapalloc对内存大小完成映射,注意flag要加上USER,因为是要映射到用户空间。通过fd找到文件节点后直接读入到得到的物理内存处,完成映射。

4.16

虚拟化这个题,看过了视频后,有了老师给的提示还是非常容易的。虚拟机在执行到某个位置触发了系统异常,那肯定要在traphandler里找,返汇编后,看到有非该特权级的指令执行出发了异常指令,那就将pc指针步进继续执行,然后代替处理复制操作,后面的错误访问内存也一样,代替执行赋值后设置pc继续执行内核。

总结

三阶段做的这些题远远不够理解arceos,所以在做完后我确定在虚拟化上下功夫,仔细研究这一块的代码。