0%

第一阶段

参加训练营让我了解到有 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使用,当然,也不能只专注在语法本身,对操作系统本身知识的学习,会更重要,非常期待!


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去进行一些有效编码了

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

第一阶段学习总结-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我来了!

阶段一-Rustlings

这个阶段主要是需要进行rust相关的学习.

其实早就有接触过rust,但是语法,尤其是所有权和生命周期这块,一直还比较生疏.

有关于所有权相关的内容主要是看了这个视频:如何一步一步推导出Rust所有权、借用规则、引用类型以及秒懂生命周期标注_哔哩哔哩_bilibili

其中关于rust作为无gc语言,大部分内存都是保存在栈上的,只有少部分是保存在栈里边.

‘a指出返回的引用与输入参数x、y之间有关联.

这个非常非常重要.

阶段二-OS内核实验

ch0-2

可以参见我之前复现rCore-Tutorial-Book-v3 3.6.0-alpha.1 文档的笔记,被公开在博客园上.

[winddevil的笔记 - 博客园

这次学习主要是从ch3~ch8的学习,重点换做了解决通过测例,和一些自己的问题.

ch3

主要是讲的一个任务切换的流程,有了任务切换之后又通过定时器中断实现了抢占式调度.

替代文本|800

ch4

这一章主要解决的是一个虚拟地址转换为物理地址的过程,说是虚拟地址,我原来以为真的改变了地址,实际上每一次调用资源都还是使用了物理地址的,利用地址空间对所有的需要访问具体物理地址的对象进行操作.

替代文本|800

ch5

这一章同样是承接了上一章的知识,讲的主要是一个进程的概念,加入了很多新的结构体,后边我应该会有时间的时候更新一下图片.

进程中最巧妙的就是使用了fork这个复制一个任务的操作,有了进程,那么就可以实现编程的简洁性,倭只需要编写一个小任务,然后再进行组合,而不是调用fn,然后自己设计各种分支结构.

有了进程,相当于把调度的工作委托给了os.

ch6

在上一章的基础上,引入了块和文件系统.

这一部分的知识学的非常的不牢靠.

但是让我印象深刻的地方是,这一章基本实现了我对之前学习的时候发现windows是可以直接”点开”应用这个操作的好奇.

那么应用保存在哪里,为什么我用U盘拷贝了还是可以继续运行.

之前学习单片机的时候很少想到我可以通过什么东西对”可执行”的东西进行操作.

通过二进制文件进行加载然后运行的操作属实惊艳到了我.

ch7

这个和ch4更加相关.之前运行rtos的时候总是想着,那么这个变量可以直接以全局变量的方式进行传输为什么我要使用各种比如信号量比如邮箱的方式,现在就一目了然了.

因为地址空间的不同所以进程之间的通信需要通过管道,也就是需要经由操作系统这一层.

ch8

这一部分让我想起了之前进行单片机编程的时候的临界段保护操作,那时候是通过非常暴力的方法关掉了所有的中断以保证这次读取不会出现问题.

或者使用原子操作保证中断无法打断单一时钟下的操作.

这里并没有和硬件和中断打交道,而是选用了三种方式,加锁\条件变量\信号量的方式.

使用银行家算法进行了调度,算法不难,但是调用本身很麻烦,需要在每一次加锁的时候对题中的变量进行操作.并且每一次上锁的时候都需要detect,那么对上锁的程序也必须进行改造.

本次体验

越到后边越忙,如果有幸进入下一个阶段一定不能好高骛远多线程操作,一定要留足时间给自己.

第一阶段练习总结

作为一名Cpper,我之前对Rust的了解可以说是毫无了解,这次受到朋友的邀请,第一次接触Rust,刚开始以为就是像C一样的过程语言。然而,当我真正开始深入学习和使用Rust时,我发现它远比我预想的要有趣和富有挑战性。特别是在进行Rustlings练习的过程中,我收获颇丰,也深刻体会到了Rust语言的强大和魅力。

Rustlings是一个设计精良的Rust语言练习项目,通过一系列由简到难的练习题,帮助开发者逐步掌握Rust的语法和特性。在练习的过程中,我遇到了许多看似简单但实则深奥的问题,这些问题让我不断思考和探索,也让我对Rust有了更深入的理解。

通过Rustlings的练习,我只能感叹面向编译器编程的魅力。

此外,Rustlings的练习还让我认识到了自己在编程思维方面的不足总的来说,Rustlings练习是我学习Rust过程中的一个重要环节。它不仅让我掌握了Rust的基本语法和特性,还锻炼了我的编程思维和解决问题的能力。我相信,在未来的学习和工作中,我会继续利用Rustlings等资源来深化对Rust的理解和应用,并不断提升自己的编程水平。同时,我也期待在未来的项目中能够充分发挥Rust的优势,写出更加健壮、高效的程序。

一阶段学习体会

早就听说过大名鼎鼎的 rustlings, 这次借着 oscamp 的机会来做一做。做的过程中发现 oscamp 的 rustlings 似乎比官方的 rustlings 加了很多私货,难度大了不少,
但是也的确把编写 很多有用的 rust 特性 和 os 过程中会用得到的一些 rust 的 feature 都涵盖了。在做的过程中,也学习到了很多以前自己没有注意或者使用过的 rust 特性。
更重要的是,通过一些题目的学习,能摆脱原来写 c++ 的思维,写出一些更 rust 风格的代码,比如返回值多用 Option 和 Result,更多的使用 match 和 if let, 而不是用原来 c++/c 风格的错误判断,
以及更多的用迭代器等方法。

一阶段学完之后,尤其是经历了大量和编译器的斗智斗勇之后,我对 rust 的理解加深很多,也对 rust 带来的相比 c++ 的很多优势有了更深的体会。相信 rust 和 c++ 的学习会互相促进。

二阶段学习体会

本科期间零零散散一致有学过 rust 和 rcore 的一些东西,由于各种各样的事情没能坚持下来。
读硕士之后刚好又系统学习了一下 rust ,正巧有同学来约我参加 oscamp , 于是就来参加。

如今再做 rcore 感觉要比本科期间轻松了很多。在游刃有余之后,能从 rcore 中汲取的知识也就更多了。
文件系统的组织方式、并发的实现和管理等,这些本科期间令我头晕转向的知识点,现在都能比较轻松地理解。也能从中窥探出一个真实生产环境下的操作系统是如何设计的。

本次实验中,前四个实验都比较轻松,思路清晰地拿下了。最让我头晕转向的是第五个实验,也就是死锁检测的实现。
刚开始被银行家算法迷惑,感觉很难实现。后来又做了尝试做了环路检测来检测死锁。但是做的过程中发现环路检测可能比较难处理信号量。于是又回过头来思考银行家算法。
结合前面尝试做环路检测的过程,觉得只要实现一套类似银行家算法的检测机制就好了。于是把代码全部推翻,从头来过很快就拿下了。

这一次 rcore 学习体验不错,希望接下来的三阶段能学到一些有意思、更贴近实际场景的东西。

rCore第二阶段总结报告

第二阶段回顾

​ 本以为第一阶段后将是一马平川,却不曾想第二阶段竟是噩梦的开始。本以为第二阶段也和第一阶段一样,只需断断续续抽出一周的零碎时间即可轻易完成,但只有亲身尝试过才会知道这种想法多么的错误,最后几乎是推掉了所有的学业任务,把一整周都投入在了rCore上才勉勉强强卡ddl写完了所有lab。

​ 第零章和到第二章可以说是第二阶段的环境配置和任务理解阶段,由于上一阶段仅仅是在mac电脑上轻松写代码,故在一开始的环境配置上还是耗费了小两天,在此过程中第一次接触到了windows的wsl,然后一步一步在实验指导书的指导下搭建了 vscode + wsl + ubuntu20.02 这样的开发环境,在阅读前面几章的文档内容后也对所学的知识、实验的相关方向有了大致的了解,并能够初步运行起来自己的rust-os。在第一章的学习过程中,我理解了应用程序的执行环境,对 应用程序、函数调用、标准库、系统调用、操作系统、指令集和硬件平台 这些概念又有了新的认识,有种学习汇编语言的感觉,另外也接触到了 裸机编程、目标三元组 这些比较新的东西。但也仅停留在有印象的层面,没能深入理解其中奥秘;第二章的内容比较全面,我了解到了应用程序执行过程和操作系统的特权级切换机制,了解了编写risc-v的链接脚本来控制内存布局、内嵌汇编、异常处理、上下文切换的实现,这些操作在代码中的实现,更是让我操作系统的课上所学映入了现实,第二章的批处理调度系统,也是一个很好的帮助我入门并理解整体的代码架构的案例。

​ 后面几章就没有那么多时间细细咀嚼了,通常都是扫两眼知识然后直奔作业,除了文件系统外,其他由于都在课上学过,因此在gpt的帮助下没有被卡住太久的时间。也很感谢用心设计该实验教程的学长/学姐,不仅让我们快速入门了os,还让我们快速了解了如何系统开发一个os的各个功能。

​ 在lab1实验就卡了很久——不会仔细品读知识中所蕴含的代码实现细节,也不会投机取巧地去看看测试用例和作业所给的提示,而仅仅是闭门造车,最终卡了许久才在群聊天记录中找到了问题的关键所在,也就是时间的记录问题,当然在写的过程中也遇到诸如生命周期等等问题,让语言基础不太牢固的我举步维艰。

​ lab2是虚拟存储多级页表实验,虽然在课上老听说页表的神奇和重要性,但从没有像本次实验这样深刻地接触过操作系统中的页表,最初做的时候由于考虑的太多又无法实现便导致一度停滞不前,后来在发呆的时候又仔细重新阅读了一下题目的要求,发现需要实现的东西都还挺简单的,而且测试用例也给的非常宽松因此很快的做完了,并没有想象中那么复杂。

​ lab3是有关进程的简单创建和调度,实现上并不困难,主要难度还是在于代码结构发生了较大变化,比如本来 task_manager 做的事情现在换成了 process 在做。

​ lab4是最痛苦的一次实验,在把ch5的代码移植过来后发现仅需要过三个测试文件即可便觉得它很简单,但真正想要得心应手地写出来需要对文件系统和代码实现有详细的理解,最终还是在听了ddl前的讲解才恍然大悟:linkat和create略像前一章所提到的fork和spawn,否则将根本无从下手然后白白浪费时间并放弃之前的一切努力。在给 inode 加上 inode_id 相关的方法后很快完成了这次实验。

​ lab5的内容相对比较熟悉,也是课上自认为十分简单的死锁检测问题,但代码框架阅读起来难度较大,最终将前面的 sys_get_time 搬过来后跟着题目的提示实现了资源分配图和死锁检测系统调用的实现

第二阶段收获

​ 这次的第二阶段学习就像一场不断挑战极限的马拉松,让我既感到疲惫不堪,又充满了意想不到的收获。在本阶段的学习中,我获得了关于操作系统核心机制的更深入理解,体验到了真实操作系统开发的复杂性和细致入微的编程要求,特别是在进程管理、内存管理、以及文件系统的设计上有了全新的认识。

​ 首先,通过批处理调度系统的实现,我理解了特权级切换、上下文保存与恢复等机制。这种直接操控硬件资源的编程体验帮助我更好地理解了操作系统在管理硬件与应用间的角色。其次,在实现文件系统的过程中,我也是初次了解了文件路径解析、inode 管理和文件描述符等底层概念,这不仅让我理解了文件系统的设计精髓,也磨炼了抽象和模块化编程的能力。

​ 同时,在死锁检测的实验中,资源分配图的设计让我更深刻地理解了进程间的依赖关系和并发控制策略,学习知识的最好方式绝对是动手实践。

​ 总的来说,这一阶段的收获不止是技术上的进步,更让我体会到了系统开发的全局性思维和精确性要求。这不仅提升了我的编程能力,也让我更有信心面对后续操作系统开发中的复杂问题。

rCore第一阶段总结报告

参加训练营的契机

​ 本人是大三信息安全专业学生,起因是在学期初老师在班级群中转发了本次训练营的相关推送,正好本学期在修操作系统专业课,再加上在过去的两年实际上没有学过过硬的技术,就希望能通过本次训练营收获到许多实际项目开发相关的东西,希望能做到技多不压身。

第一阶段回顾

​ 本阶段的主要任务是根据 rust语言官方圣经 来学习rust语法,并在简单的知识训练、算法实现中掌握基本的编程逻辑和rust语言的独特思维。在学习过程中最大的感受就是,这是一门非常“麻烦”(或者说拗口)、非常底层但却非常“安全”的语言。

​ 在进一步地阅读文档和代码实操的过程中,我也深深地体会到了rust语言的魅力,很多在其他语言中不需要关注的问题,都是rust使用者的家常便饭,例如所有权与借用、生命周期、模式匹配、并发和线程、内存管理、特征泛型、智能指针、宏等等全新的概念,在学习的过程中,也能十分自然地和以往所写过的语言进行对比,也能十分自然地联想到自己所学的专业知识,整个学习过程是痛苦而充满趣味和成就感的。

​ 最终也是断断续续地在国庆后完成了110分的编程题目,虽然很多地方都有囫囵吞枣、只求大概的不好处理,但还算是初步打开了rust语言的大门。