0%

2025春季开源操作系统训练营总结-李明涛

arceos 总结

前言

arceos 是基于组件化的思想构建的,通过使用不同的组建,可以分别编译出Unikernel, Monolithic Kernel, Hypervisor三种内核架构。我是第一次深入了解Unikernel,Hypervisor这两种架构,几乎没有合适的书籍去展开这些内容,整一个五一假期下来,我对它们有了初步的理解和探索经验。

Unikernel

Unikernel 这部分是渐进式地学习,U.1~U.8一共8个Unikernel的内核,其中插入四个练习:

  1. 带颜色的输出
  2. 手写一个HashMap
  3. 实现bump内存分配算法
  4. 在axfs_ramfs下实现rename功能

第一个任务,只要理解了用户使用println!()的调用流就可以完成:

1
main --> axstd --> arceos_api --> axhal --> 硬件

这样的调用关系也基本和arceos中系统架构的层次关系吻合:

1
硬件 --> axhal --> ax_modules --> arceos_api --> axstd --> user

第二个任务,手写一个HashMap,这个任务其实很让人为难,因为它非常具有灵活性,简单的可以从OI wiki上面把哈希表的C++代码“翻译”成rust,再实现一个拉链法就完成了。复杂的可以参考rust的标准库,用裸指针操作,加上PhantomData标记生命周期和所有权。

我偷了点懒,实现了一个丐版的,我首先是参考xxhash实现了一个Hasher用于支持hash操作和随机数支持,然后包装了Vec用于内存分配和动态扩容的机制。避免hash冲突的方案,我选择了比较简单的线性探测法。

第三个任务,bump内存分配算法,基本原理就是维护一个指向内存起始区域的指针和一个偏移量,根据传入的Layout依次分配内存,无法单独释放内存块。只需要实现arlyAllocatortrait就可以接入内核中了。

第四个任务,虚拟文件系统会调用具体的文件系统进行操作,我最终找到调用的终点是axfs_ramfs下的DirNode结构体中,接下来就很简单了,就是修改两个DirNode下的BTreeMap<String, VfsNodeRef>

唯一一点胃痛的就是arceos/modules/axfs/src/root.rsrename函数中,src_path去除了挂载点的前缀,但是dst_path没去掉,这样实际上就不知道,dst_path是相对ramfs还是相对主文件系统根目录的了。

Monolithic Kernel

在宏内核中,基于Unikernel引入了用户态和系统调用的概念,可以看到相比U.8,M.1中增加了一些额外的模块。但是相比从零构建,我们大量复用了原有的模块,发挥了组件化内核的优势。

宏内核这部分只有一个练习,实现sys_mmap系统调用,并能够对文件进行内存映射。如果真的想要实现一个完整的sys_mmap,恐怕有些复杂。我们需要一个新的内存映射后端对文件进行映射,第一,要求能够从文件描述符中访问文件;第二,要求能够接受来自文件系统的信号,并及时将脏页同步到磁盘中。

这工作量确实有些大,所以我选择了参考提示信息“可以参考m_1_0中加载应用到用户地址空间的代码段”,先使用fd读取源文件的内容,使用alloc的后端分配内存,在查找用户态的页表获取对应的物理地址,最后写入原文件的内容。于是完成了本次练习。

Hypervisor

这一部分,在Unikernel的基础上引入RISC-V的H扩展,获得了虚拟化的能力。但是目前虚拟机的能力还非常的弱,准确来说只有两个对象,虚拟地址空间(aspace)和虚拟处理器(Vcpu)。

这一部分的练习中,我们只需要了解客户端在 vmexit_handler 中处理异常,然后针对我们的测试样例给客户端的a0a1寄存器进行赋值即可。

第三阶段总结

相比rcore,arceos复杂了许多,不过arceos中的内容在rcore中都有了一个丐版的实现,我做起来也快了不少。

在arceos中第一次了解到了组件化内核的概念,这三种不同类型的内核都可以通过像搭积木的方式,把需要的组件加上,再补齐特定的细节就可以实现从Unikernel到宏内核或者Hypervisor的跨越。

最后的最后,我谈谈自己的感受。开源操作系统训练营真的是一个非常优质的课程,有非常专业的教授老师,有积极回复的助教团队,在这里我一个普通的大学生感受到了深深的震撼,也许这命运的齿轮就在这里开始转动。