0%

greatbridf-2024秋冬操作系统训练营三四阶段总结

三、四阶段学习总结

ArceOS及Starry项目

ArceOS

ArceOS是一个组件化内核,我的理解就是把传统内核中的那些模块都变成一个一个的组件,如果你需要fs相关的功能,你就把这个包弄进来,编译进来,然后就可以在里面直接用他的功能。这样给使用这个内核的人一种灵活性,同时每个模块相对独立,也让不同的模块之间的耦合较松,维护进来也很方便。

另一个好处就是我可以在这个项目的基础上做出我自己的扩展,比如说第四阶段的项目Starry。或者是如果我只需要用到其中的一些功能,例如我在一些嵌入式设备上使用,那额外的功能就可能完全没有用,还会有额外的开销,我就可以把我不需要的功能全都干掉。

具体来说主要看了的一些模块:

  • axhal管理了和平台相关的那些东西,这样可以把平台相关的代码(尽量)全都压缩到一个模块里,只暴露出一个接口就可以了,避免漏得到处都是
  • axmm实现的是虚拟内存管理相关的功能,提供了一些有关的抽象。里面用了MemorySet这个东西,把具体的实现给分开了(到Backend里),扩展性也比较好。
  • axtask实现了任务管理的功能,提供了很好用的接口,每一个任务可以被很容易地创建。这个项目里用来实现用户进程也很方便。
  • axfs实现的是文件系统相关的功能。
  • axns实现的是类似于Linuxnamespace的功能,可以让一些不同的应用有自己独占的资源。

等等

Starry

Starry是在ArceOS基础上做的一个宏内核的项目。我的理解大概就是,使用ArceOS提供的这些模块的基本功能,在这个基础之上做出我们常见的宏内核的样子,并且可以和我们现在常用的Linux等内核实现兼容,这样有很多的好处。

比如其中之一就是,用传统的方式来实现一个宏内核,很有可能会得到一个很乱很庞大的代码树。但是ArceOS他每个模块都分开来,本身各个模块的分工都是很清晰的,我们只需要用这些已有的功能,把我们需要的东西给组装起来,然后再加上额外的一些东西就可以了。这样我们写起来也很快乐,得到的代码也比较好理解。

我做的事

一句话说一下的话,就是在这个项目框架的基础上实现了一些系统调用。

任务管理

ArceOS的任务管理基本上是保持了简单的风格,有了大多数我们所必需的任务管理的内容,同时也把类似于Linux中的进程组啊,会话啊这些内容给拿掉,保持了简洁。他有一个TaskExt的设计,就是如果我们需要什么额外的功能,我们可以在这个位置加上我们所需要的field,这样就实现了扩展性。

就比如在这个项目里,我们对其扩展,加上了pid的字段。ArceOS中的任务已经有一个编号了,但是我们希望将对用户空间可见的部分和ArceOS中这些实现相关的部分给分开来。所以我们再添加了一个额外的pid,专门用于用户空间进程的管理,以后如果我们实现了进程组,会话等,可以再在这些加上pgidsid等,或者可以加上侵入式链表来把这些Task给串起来等。

然后还加了用于实现brk的变量,记录当前进程的break的位置。另外,用户空间程序的地址空间和Context也放在这里。因为每一个用户态程序都需要自己的(也有可能和其他人共用)虚拟地址空间,所以把这些放在这个位置,而不需要去修改原本ArceOS的任务部分。

AxNamespace

其中还用到的一个部分就是AxNamespace,但是这个用的觉得有一些问题。这个东西本来的作用大概就是我可以虚拟出几个空间,在这些空间里的进程都有自己的一些资源。在AxNamespace的描述里说,可以实现每进程专属的资源。他的实现是类似于 Thread Local,我有一个全局的数据,然后我可以选择,对于每一个任务,我在访问的时候要不要全都用这个全局的数据,还是每个任务都有自己的数据。

实际使用中发现,他在初始化每个任务自己的数据的时候,是直接把全局的这个数据给Copy过来。也就是说,如果我想把东西放到这个里面,那我需要这个东西都是Copy的。但是CURRENT_DIR这样的东西,他用的是AxResource,或者也叫Arc<Mutex<T>>,那把这个东西直接复制其实应该是会造成一些问题。其一就是他根本没有实现希望有的复制的语义。第二个就是这样实际会造成内存泄漏,因为这样相当于是造出了一个没有引用计数的Arc。如果我要是用一个Copy的东西呢?我觉得这样也比较麻烦。。。或者说这个实现在某种意义上有点像TLS。所以说这个AxNamespace的使用是我感觉有些疑惑的一个点。

实现的系统调用

实现了clone,但是具体的flags没有处理,只按照fork的语义+返回并且用给定的栈。这个位置应该加上Copy on Write的支持,在MemorySetBackend里加上这个,给每个页一个标记,然后在处理Page Fault的时候如果这个标记有了,就把这个页给复制一份,然后取消共享(虽然因为时间的关系没有实现)。我觉得Backend这个设计很好,在一些库里可以看到。这个设计让我们可以很方便地扩展三方库给的一些功能,同时不破坏这个库本身的代码和结构。

内存管理相关

现在的内存管理部分还是非常的简单,没有CoW,也没有懒分配,这个是我希望可以进一步完善的部分。axmm还有其他的一些库提供了很好的抽象,我觉得在这些基础上完成这个部分应该会相对比较轻松。

文件系统相关

实现了opencloseread还有dup等。这些都比较简单,因为ArceOS本身已经大致提供了这些功能的函数了,我们只需要把这些功能给封装一下。

在做这个部分的时候,想到了一个玩法。因为Starry本身就是一个ArceOS的应用,那我们可不可以在一个ArceOS的基座上同时跑两个Starry呢?现在这样实现,他们的进程之间就是分开的(都在TaskExt中有各自管理的pid),并且我们可以将他们在文件系统中的根目录给分开,比如说ArceOS这边的/mounta是其中一个的根,/mountb是另外一个的根。这样有些类似于是容器了,但是可能能提供更好的隔离性?

碎碎念

期末周杀我,这次项目中没做很多的事,还是感觉很遗憾吧。但是看了ArceOS的架构以后,感觉有很多的收获,了解到了一些新的想法。希望有时间的时候,可以进一步完善这个项目。参加这次训练营非常开心。