0%


title: 2025春夏开源操作系统训练营总结-mf1bzz
date: 2025-05-06 12:45:01
categories:
- 2025春夏季开源操作系统训练营
tags:
- author: MF-B
- repo: https://github.com/MF-B/Note
- blog: https://blog.mf1bzz.cn

OS Camp Stage 1

感想

一阶段是Rust编程
Rust有很好的官方教程,也有很多第三方资料

我是直接开始做rustling来学习的
遇到不懂的就去翻手册,我看过的参考资料都记录到了下面

OS Camp Stage 2

感想

二阶段是rCore学习
rCore一共九章,篇幅很大,前前后后大概花了20天的时间,整个过程还是非常有意思的

二阶段对我个人的提升很大,由于之前没有学过操作系统,rCore的学习让我理解操作系统是什么,之前一些对计算机的模糊概念也渐渐清晰了起来,也顺便提高了我的Rust编程能力

看的比较多的就是Risc-V的参考手册了

OS Camp Stage 3

感想

虽然做二阶段的时候看过一些ArceOS的代码,但是并没有看懂,不过经过第三阶段的学习之后,我逐渐了解到了ArceOS的组织方式,相比于rcore,拓展性是肉眼可见的提高了,也更易于维护.

总结

参加训练营让我学到了很多,但也暴露了我的很多问题,我意识到我的算法能力太过于薄弱,学完学校教的数据结构之后就几乎没有怎么碰过算法了,做三阶段挑战题时也是花了一整天也没有达到最高分数;
不过不暴露缺点的话,也谈不上要改进了.

2025春操作系统训练营四阶段报告

第一阶段 - Rust编程

  • 这一阶段主要就是了解学习Rust的语法和特性, 以及完成所有的rustlings题目, 以及实现一些基础的数据结构和算法, 为之后的项目内容做准备.
  • 我对rust的语法已经比较熟悉了, 其实rustlings之前也做过一遍, 所以很快, 但数据结构和算法的rust实现有点忘了, 这部分花了点时间

第二阶段 - OS设计实现

  • 仓库连接: https://github.com/LearningOS/2025s-rcore-jizhaoqin
  • 这一阶段花了挺多时间, 因为一个完整的os内核内容和代码真的很多
  • chapter1 应用程序与基本执行环境
    • 这一届内容比较少, 主要是关于如何实现一个最小内核, 以及RustSBI使用的一些问题
  • chapter2 批处理系统:
    • 由于我以前没有接触过risc-v指令集和汇编语言, 所以在理解汇编指令, 链接脚本, 还有特权级的切换方面花了很多时间, 最后也是能够理解实验里给的代码都有什么作用
    • 另外, 我找了内容更多的v3版文档阅读前两章, 发现内容确实很详细, 但不适合做实验, 因为对我来说是在是太多了, 当个参考书挺好, 遇到camp文档疑惑的地方去查以下非常有用, 因为逻辑是一样的, 但是跟着v3文档一步一步写代码实在是很痛苦, 主要是进度太慢了, 没有反馈动力不足继续做下去了.
    • 所以后来我就主要看camp文档了, 而且不再一步一步跟着自己实现, 主要是在每一章的练习部分, 在实现的过程中再去仔细理解每一个模块的作用, 这样会好很多对我来说, 理解地也很快.
  • chapter3 多道程序与分时多任务
    • 这一章实现了简单的抢占式任务调度, 主要内容是程序上文的保存和切换
  • chapter4 地址空间:
    • 这一章内存虚拟化是非常重要的内容, 之后内核态和用户态就会在内存映射上隔离, 区分更明显了, 同时对上下文切换的汇编代码进行了一些补充修改
    • 这一章对多级页表的介绍其实不详细, 但是我以前实现过x86架构上一个简单的4级页表, 以及动态内存分配器, 所以整体理解没有问题, 但是需要了解更多关于SV39多级页表的一些细节
  • chapter5 进程及进程管理:
    • 介绍了进程的抽象的实现, 在这个实验里相对于内存虚拟化来说并不难理解
    • 通过进程实现经典的sys_fork()和sys_exec()系统调用
    • 而且从这一张开始有了一个简单的shell了
  • chapter6 文件系统与I/O重定向:
    • os的又一大关键功能, 提供文件抽象和接口
    • 这一章是目前为止最费劲的一章, 因为抽象层数太多了, 实现系统调用的时候非常容易搞乱, 而且到这里代码已经很多了, 层数也很深, 花了非常多的时间去理解调用的每一层都干了什么事, 但一些没有直接用到的API没有多看. 好在最后实现完成后, 本地测试一遍就通过了, 还是挺好的.
  • chapter7 进程间通信:
    • 主要实现进程间管道通信, 这里基于文件抽象来实现
    • 在shell里还实现了重定向符号>, <
  • chapter8
    • 简单的笔记:
      • 线程的用户态栈:确保在用户态的线程能正常执行函数调用;
      • 线程的内核态栈:确保线程陷入内核后能正常执行函数调用;
      • 线程的跳板页:确保线程能正确的进行用户态<–>内核态切换;
      • 线程上下文:即线程用到的寄存器信息,用于线程切换。
    • 线程抽象, 并发的要求, 锁的实现, (一般)信号量与实现, 条件变量
    • 这一节还好, 对锁还算比较了解, 然后互斥锁是2元信号量, 也比较好理解, 就是条件变量不熟悉, 因为结尾的练习似乎不太需要, 对这一部分也没有改动.

第三阶段 - 组件化操作系统

  • 仓库连接: https://github.com/LearningOS/2025s-arceos-jizhaoqin
  • [print_with_color]:
    • 可以使用ANSI转义序列, 修改终端输出的颜色
    • 可以在用户层println!, axstd的输出宏定义处, 或者axhal处修改putchar, 影响的范围也不同
  • [support_hashmap]:
    • 语言提供的alloccrate里中提供了一些常用的集合类型比如VecBTreeMap, 禁用标准库时只需要提供全局动态分配器就可以使用, 在Acreos里打开allocfeature就行
    • 但是HashMap除了分配器还需要提供随机数生成器, 所以不在alloccrate里需要自己实现.
  • [alt_alloc]:
    • 实现一个简单的分配器BumpAllocator
  • [ramfs_rename]:
    • 文件系统相关的实现和API
    • 对于rename来说, 其实就是在目录文件的数据块里删除一个条目, 同时新增一个条目, 但都指向相同的索引节点, 理论上也可以直接修改条目中的文件名, 但更复杂需要做出大量修改(因为现有条目储存用的是BTreeMap把文件名作为key不支持修改), 会引入额外的逻辑开销而且不会提升性能, 所以使用现有的删除和新增功能就好了
  • [sys_mmap]:
    • 同rCore里sys_mmap的实现类似
  • [simple_hv]:
    • hypervisor虚拟化相关的内容

第四阶段 - 项目三: 基于协程异步机制的操作系统/驱动

  • 仓库连接: https://github.com/jizhaoqin/arceos/tree/dev-async-irq
  • 汇报连接: https://docs.google.com/presentation/d/1VZuvpDa1Ot9joiWxl2y-eviw-mX34QQXLZYLFYfCR1c/edit?usp=sharing
  • 选题方向:
    • 主要目标是尝试对部分非实时中断异步化, 具体以uart串口通信为例, 实时意味着需要立即处理完毕, 非实时中断则不要求中断信息能马上处理完毕, 对这种中断我们可以将其放在后台运行而不阻塞当前逻辑, 比较适合将其转化为异步任务进行处理.
    • 需要注意的是, 我们一般要求所有中断都要求立即返回, 但这并不意味着中断已经处理完毕, 比如网络包下载, 或者高负载串口通信, 有些信息处理比较耗时, 这时为了快速结束中断, 我们可以将未经处理的数据放入缓冲区队列, 然后在结束中断前通知异步任务进行处理.
    • 另外由于目前Arceos对几乎所有外部设备都采用轮询方式, 所以在异步化之前, 先要将其改造为基于中断的方式.
  • 过程:
    • 架构和具体目标: aarch64 qemu virt platform的uart中断异步改造.
    • 首先在axhal中给对应platform注册uart中断并启用, qemu将terminal的用户输入模拟为串口通信, 经测试arceos能够按照预期以中断的方式接收串口信号.
      • 这一部分的难点在与梳理清楚arceos的中断架构, 注册和调用流程, 以及各架构axhal, axruntime, axstd, arceos_api之间以及内部的代码和依赖结构.
    • 之后尝试异步改造uart的中断处理函数. 如之前提到的, 我们将中断处理分为两个部分:
      • 第一部分是同步的, 需要原封不动地接受所有信息并将其推送到缓冲区队列, 并发送信号表明有数据需要处理.
        • 这一部分的难点在于如果处理程序是异步的, 我们如何从同步的中断处理函数中发出合适的通知信号.
      • 第二部分是异步的, 为数据处理程序, 在这里我们采取异步的方式, 由一个异步运行时维护有多个中断第二部分数据处理程序的队列(由于目前只注册了一个中断, 队列中只有uart中断的异步处理任务), 并进行调度, 与内核线程调度不同的是, 这些处理任务都在同一个线程中.
        • 这一部分的难点在与, 如何构建一个非标准库环境下的异步执行器, 来轮询和调度这些异步任务.
  • 成果:
    • 最终完成了aarch64 uart的中断注册,
    • 实现了中断处理函数的异步改造,
    • 构建一个内核异步运行时并进行调试, 以完成异步中断处理的执行和调度工作.
  • 未来可能的方向:
    • 整理代码结构, 符合arceos的规范, 形成良好的文档
    • 尝试兼容更多中断类型, 用统一的异步中断处理异步运行时处理更多类型的非实时中断.
    • 兼容更多架构
    • 优化异步运行时的调度逻辑, 以及实现优先级调度等功能.
    • 将异步运行时替换为更成熟的embassy
  • 实现过程中遇到的困难:
    • 尝试注册键盘中断进行测试, 发现需要开启qemu graphic实现显示设备驱动, 而且兼容性差, 所以不搞键盘中断了, 直接搞串口中断, 目前arceos的实现都是轮询;
    • x86_64 qemu q35 平台没查到COM1 uart的中断向量, 导致一直没能成功注册中断, 而且x86的x2apic架构比较复杂, 执行了irq映射难梳理, 最后花了很多时间也没搞明白中断向量到底是啥;
    • 后来转向aarch64, 成功注册uart中断, 并测试表现良好符合预期;
    • 尝试异步化改造中断处理, 查看embassy的实现有些复杂不好拆解, 最后决定从头手写一个简单的异步执行器, 花了好大力气才搞定, 测试能工作;
    • 尝试把异步运行时和中断处理结合起来的时候总是有交叉依赖的问题, 最后把异步任务通知逻辑和执行逻辑分别放在axhalaxruntime, 才最终解决交叉依赖.
    • 执行器阻塞线程不主动yield, 直到一个周期后被抢占才切换到其他线程, 而其他线程正常yield, 这使得执行器线程占用了几乎所有CPU时间
    • 最后又更改了中断处理流程, 添加了两个缓冲区才最终把逻辑跑通
  • 其他:
    • 为较大项目添加特性是一件很困难的事, 除了考虑本特性的实现, 还要嵌合进整个项目的组织框架和编译逻辑中, 不敢想象如果没有好的代码架构, 抽象以及解耦, 可以想象越到后来, 最终将达到一个极限, 使得这一工作几乎不可能完成.


title: 2024秋冬开源操作系统第一阶段总结-yqthz
date: 2024-11-06 20:42:18
categories:

  • report
    tags:
  • author:yqthz

一直想学习Rust, 趁着这次训练营的机会, 开始了我的Rust学习, 初学Rust时, 就感觉Rust的设计十分现代, Rust的所有权机制让内存管理变得十分高效且安全, 减少了很多的内存问题, Rust的所有权、借用和生命周期模型可以在编译期防止常见的内存错误(如悬空指针、双重释放等),无需依赖垃圾回收器。

最初,我发现所有权模型与传统编程语言(如C++或Python)非常不同。理解所有权和借用规则如何影响变量的生命周期和作用域是一大挑战, 通过Rustlings的练习, 我逐渐掌握了Rust的语法和特性, 也感受到了Rust的魅力, 在编写Rust代码时,需要细致地思考数据的生命周期、所有权和借用,这培养了我编写安全代码的习惯。

Rust的学习让我认识到了一种与传统语言不同的编程思维模式,也让我理解了系统编程中的许多细节。虽然Rust的学习曲线相对较高,但它所带来的性能和安全性是非常值得的。我期待在未来的项目中更多地使用Rust, 充分返回Rust在内存安全和性能上的优势


title: 2024秋冬开源操作系统第二阶段总结-yqthz
date: 2024-11-08 13:24:05
categories:

  • report
    tags:
  • author:yqthz

rcore的实验还是有一定难度的, 需要仔细阅读框架代码, 了解rcore的整体设计
lab1是实现sys_task_info系统调用, 比较简单
lab2是实现在启用虚拟地址的情况下重写sys_get_time和sys_task_info, 并实现sys_mmap和sys_munmpa系统调用, 难度较大, sys_get_time和sys_task_info仔细阅读sys_write的实现就可以完成, sys_mmap和sys_munmap做了一定简化, 在实现过程中需要对框架代码中的地址空间, 页表有较深的理解
lab3是实现sys_spawn和stride调度算法, 比较简单
lab4是实现硬链接和获取文件信息的系统调用, 难度较大, 也是我花费时间最多的一个lab, 需要仔细阅读框架代码中文件系统的实现, 需要对inode和disk_inode有较深的理解, 最开始尝试实现的时候, 卡在了如何读取disk_inode上, 后面又重新读了一遍框架代码, 一点点把文件系统的各个层次弄清楚, 最后成功完成了这个lab
lab5是实现死锁检测, 这个lab不需要阅读太多的框架代码, 只需要理解死锁检测算法即可, 难度一般, 最开始的实现的时候, need矩阵花费了我较多时间去理解, 在反复阅读测试用例和算法后, 我开始理解了这个算法, 最后成功实现了这个算法
最后, 非常感谢训练营将这么优质的内容开源, 同时提供了这么一个平台把大家聚集在了一起, 在与大家的交流和学习中, 我收获很多, 在阅读文档和框架代码的时候, 对os的许多概念有了实际上的理解

第三阶段总结报告

学习

跟着看了大课,第一周的实验题尝试解决了,到第二周的宏内核后时间紧促就先看课了。

这里我谈谈我对于课程内容的理解吧。

首先是Unikernal,直观的第一眼看的话,Unikernal像是不划分用户空间和内核空间的操作系统,
同时也没有页表机制,不开虚拟空间,内核是一次写好的,app加载是配置文件一个一个分配的。这样的内核
就像是实验室产品一样,用户都是开发者权限,它的性能也是极度的优异。不过嘛,不分权,所以安全性很容易受威胁

接下来是宏内核,宏内核是常见的平时家里用的操作系统模式,宏内核地址空间的引入好处益处在学习操作系统时是所有人必背的。
它的内存分配,进程调度,也都是耳熟能详的。

最后是这个hypervisor,我最开始学习的语言是C,后面走了C++,所以对于虚拟机的机制只是略有耳闻,这里更深入的
探讨了虚拟机是如何实现,虚拟机的实现使

思考

异构扩展化的操作系统内核是个很令人兴奋的话题,就是这个内核你不能当他是某一个具体的内核,它可以执行各种app,关于异构
在智能物联这我有个想法,就是如果说是各个物品之间的交互的话,可以用统一的协议。那如果,这些物品可以在物理上链接在一起,
那么可不可以执行一个新的效果?就是比如,全屋有一个统一集中的管家,它是有个物理实体的”大脑“的,很多家电与它是进行”硬链接“,进行更快速,更高效的交互,控制。
当然,也可以通过网络链接,不过这是提供了另外一种方式。

方向

我选择本期的方向四,基于协程异步机制的操作系统

第一阶段

参加训练营让我了解到有 rust 这门语言,以前写c/c++习惯了指针的自由操作,刚开始非常不适应,但随着之后的学习越来越爱。
Rust 兼顾安全与性能,Rust的所有权机制让内存管理变得十分高效且安全, 减少了很多的内存问题, Rust的所有权、借用和生命周期模型可以在编译期防止常见的内存错误(如悬空指针、双重释放等),无需依赖垃圾回收器。Rust 编程思维不同于传统的面向对象,我认为更像是面向数据。

第二阶段

训练营给了我交流与实践的平台,通过参加此次训练营我学到了很多关于操作系统的知识,也让我了解到了在操作系统领域最新的研究与技术。
从裸机运行到单道批处理系统,学习了如何通过操作系统将程序与硬件隔离,提高安全性和资源利用率。rCore通过硬件的运行特权级划分和系统调用来实现多程序批处理,将程序编译链接成bin文件,加载到内存中的约定地址执行。进一步地探索了进程调度的机制,理解了时间片和CPU利用率的关系,以及如何通过TCB(任务控制块)来维护程序的关键信息,实现程序的切换和调度。
在内存管理方面,学习了从物理地址到虚拟地址的转变,以及MMU(内存管理单元)的重要性。rCore采用SV39内存管理策略,通过页机制和多级页表提高了内存的灵活性和安全性。对外存的管理,我了解了文件系统如何抽象和管理系统资源,以及rCore如何通过文件描述符(fd)框架来统一管理文件和设备。
线程与进程的学习让我认识到了操作系统调度的复杂性。RCore通过线程的引入提高了响应速度和调度效率,同时使用信号量和互斥机制来解决线程间的冲突问题。
总的来说,RCore的学习不仅加深了我对操作系统的理解,也锻炼了我的系统编程能力。通过实践,我对操作系统的许多概念有了更实际的认识。

Rustlings 练习总结

作为一名前端全栈开发者,刚开始学习Rust时,给我的感觉是没想象中的难度那么高,学起来还挺轻松…
然而,还是太年轻了,当我开始真的用起来之后,我发现,编译器成为了我前进的“恶梦”,它无时无刻不在教我做人,总是会在不经意间鞭挞我:“你,还很菜呢!”
所以,慢慢的,我开始放弃了保守的学习方式:“先将文档中的内容都大致学会,并记下来”,它让我一直停留在学习的舒适区,对学习Rust来说是很低效的。
Rustlings 其实就是一种很好的学习语言的方式,通过大量的几乎全覆盖式的Rust练习,在练习中不断遇到问题,并解决问题,就像打怪升级,心理上会不断的得到激励感,并不断的做下去。
通过Rustlings的110道题目的练习,其实也让我意识到了,自己以为的会使用Rust了,只是井底之蛙吧了。
练习的内容虽然都在文档中,只看文档学习的化,其实有时候会忽略这些知识的真实用途是什么,也就无法在实际项目中灵活的去使用了。
通过这段时间的练习,不一定让我在Rust的熟练成都有很大的提升,但是让我看到了一个Rust用法的大纲,这已经是一个很好的开始了。
希望在接下来的开发里,不断精进对Rust使用,当然,也不能只专注在语法本身,对操作系统本身知识的学习,会更重要,非常期待!

第一阶段学习总结-ZhongkaiXu

写在前面

这是第二次写rustlings,两个月前应实习要求第一次学习rust和rcore,这次和上次相比稍微熟练了一些,从最开始的一头雾水,到现在已经对rust的简洁性佩服得五体投地。接下来要一些smmu相关的开发,借着这个机会再熟悉了一下rust。以下是一些学习心得。

学习心得

我认为的rust的核心思想

我觉得rust里最重要的是所有权机制,一个value只能对应一个所有者,即使是函数传参也是一样,虽然刚开始有些不习惯,但是慢慢发现对于锻炼系统软件开发者的思维很有效。

文档

在做题的时候我会同时打开rust文档,因为太多东西记不住了,需要随用随查,抛开水平不够,感觉这还算是一个不错的习惯,开了一个好头,毕竟后面几个阶段的学习必须依赖riscv/arm的手册。

最有挑战性的

我觉得在使用rust开发过程中,最难的地方在于如何把程序写的“rust”,比如对于寄存器的访问,rust中有一些优秀的宏如 registers_struct! ,第一次看到这个东西之前还一直停留在c风格的编程思想,包括写的一些算法题也是没有完全发挥出rust的语言特性,希望在后面学习的过程中多参考一些优秀代码,养成好的习惯。

未来展望

马上进入二阶段的学习,临近6月也要做很多其他的工作,希望能做到WLB吧,把握和优秀的同学们交流的机会,学到更多东西。

第二阶段学习总结-ZhongkaiXu

写在前面

终于在最后一天完成了五道题。

这是第二次写rCore的课后练习题了,之前偷的懒也还回来了。前三个练习之前写过,就还算顺利,后两个卡了蛮长的时间。

学习心得

模仿

其实练习里面需要自己构思代码的部分不多,大部分都是在原有代码的基础上添加一些辅助的功能,只要能设计好思路,剩下的就是模仿已经实现的代码。

比如mmap的实现,我最开始想用现成的 insert_framed_area,然后还写了一大堆判断是否重复映射的函数,结果在munmap的时候又要整个考虑释放area的部分页,写的自己都懵了。后来回头看原有代码的实现,发现其实mmap就是一个 insert_framed_area 的删减版,不需要area那么大的粒度,直接模仿area里面的btreemap设计一个容器,再重用 insert_framed_area 的代码就行了..

再比如发现自己还是没法摆脱c的风格,for能套个好几层,不过好在能想到rust里面应该不用这么麻烦,然后回头翻原有代码,看看其他地方怎么用迭代器的。

大胆写 反正有rust_analyzer 反正可以rollback

现在写rust没有那么提心吊胆怕和编译器同归于尽了,还是自动补全的功劳,很多地方分不清要不要解引用、分不清数据类型,不过rust_analyzer会搞定的。

有些时候乱写一通,最后发现内核挂掉了,只好rollback了,也在群里问过把仓库污染了怎么从头开始,不过大胆写也好过不写,经过n次rollback总算能上手敲代码了。

未来展望

第三阶段hypervisor我来了!


title: 2024春夏季开源操作系统训练营第一阶段总结报告-fengtdi
date: 2024-04-24 21:38:58
tags:
- author:zlh20040308


2024春夏季开源操作系统训练营第一阶段总结报告

前言

了解到这个训练营源自一次机缘巧合,刚学完操作系统的鄙人在b站刷课时无意刷到了前训练营的导学部分,并在评论区看到了up主留下的链接,点进去一看正好都是我很感兴趣的方向,而且学习资源和github页面都整理得很完善,于是果断加入了

Rust编程基础

初探

第一阶段的的主要任务是学习Rust语言,刚接触这门语言时候的第一感觉就是概念十分的多,有些概念甚至看起来匪夷所思,如生命周期标注,我十分不理解为什么Rust要这么设计,但是秉持着能跑就行的原则,还是硬着头皮和编译器作斗争

初窥门径

带着以上这些问题,我找到了斯坦福大学CS110L这门课,这门课并不是教学生如何进行Rust编程,而是希望通过Rust的视角反映出当今两种主流内存分配机制——手动管理(malloc&free)和垃圾回收(GC)——的不足,在其三节课就主要讨论了它们所会遇到的问题:

  • 手动管理(C/C++)

    C/C++的类型系统对内存所有权的表达能力是十分有限的,以至于工程师在设计函数接口时会显得十分臃肿,还必须附上大量的注释来告知调用者去担负起管理内存的责任,也就是说内存的管理取决于程序员的自觉性,这就导致程序员经常会忘记之前申请过释放内存,而且随着工程的不断壮大,这种错误会不可避免地发生

  • 垃圾回收(Java)

    Java通过某种类似于引用计数的方式来自动回收内存,但这种设计会带来性能上的损耗(回收机制过于复杂)

而Rust便带来了属于它的第三种方案,那就是所有权机制,在这种机制下,内存管理会变得高效且安全,这得益于它强大的静态检测机制,能够在编译时期就规避掉很多内存泄露的隐患

但这也是有代价的,既然要求在编译时期就能发现错误,那么Rust编译器就会要求程序员在编码时附带足够多的信息供它推断,也就出现了类似于生命周期标注这些语法

牛刀小试

在初步过完几轮Rust基础并完成了rustlings之后,便开始着手用Rust复刻了一些之前写过的小项目(当然,还有那令Rust新手望而生畏的链表),在这段过程中越发能感受到Rust的一些设计理念在影响着我的编码习惯,也引起了我对与内存安全的思考

总结

在经历了这一阶段的学习后,虽然我到现在也不认为我是一个Rust程序员,但是也多多少少能用Rust去进行一些有效编码了

十分感谢第一阶段中为我答疑解惑的老师和同学,同时更要感谢开源操作系统训练营提供了这么一个平台把大家聚集在了一起,我十分喜欢这里的学习氛围,大家一起交流着学习上的疑惑并提出自己的见解,这开源的理念也使我收益颇丰