0%

一阶段总结

前言

其实很久之前就一直想完整的过一遍rcore,奈何时间总是不允许。这次正好在写毕业论文,就抽出一点时间。

过程

第一阶段的rustlings其实几年前就做过一次。没有太多可讲的点,但是训练营似乎增加了几道之前没接触过的数据结构题,应该属于原创内容,还是比较有趣的。几种数据结构都是比较经典的,但是由于rust语言的特性,诸如链表或是二叉树结构的节点中,子节点都使用了Box智能指针来保存。在一般的传统语言,诸如c/c++,我们会直接保存该指向结构的指针,而rust中,裸指针的操作是不安全的,所以题目中使用Box将节点结构包裹起来。
这里有一个经典入门问题,为何不在结构中直接保存同样结构的子节点而是使用指针呢?原因在于循环嵌套的结构体会导致编译器无法确定结构体的大小,而指针(当然也包括Box)是固定大小的,从而使得在循环嵌套的情况下,能让编译器在编译期确定结构体的大小。
对于指针的操作,习题中出于简单考虑,直接在unsafe中使用裸指针操作解决了,实际上,通过使用其它智能指针,合理的设计结构体,是能够完全避免使用unsafe的,这里就不展开说了。希望能够顺利完成所有训练。

二阶段总结

二阶段的内容前面和blog-os基本没什么大的区别,因为以前和洛佳一起翻译过一次,没什么太多能讲的。主要是文件系统这一块,之前没有太多了解。文件系统的结构从某种程度上来说和内存的分页机制很像。另外需要注意的是软硬链接的区别。

  • 硬链接(hard link) ln
    • UNIX文件系统提供了一种将不同文件链接至同一个文件的机制,我们称这种机制为链接。它可以使得单个程序对同一文件使用不同的名字。这样的好处是文件系统只存在一个文件的副本。系统简单地通过在目录中建立一个新的登记项来实现这种连接。该登记项具有一个新的文件名和要连接文件的inode号(inode与原文件相同)。不论一个文件有多少硬链接,在磁盘上只有一个描述它的inode,只要该文件的链接数不为0,该文件就保持存在。硬链接不能对目录建立硬链接!
    • 硬连接是直接建立在节点表上的(inode),建立硬连接指向一个文件的时候,会更新节点表上面的计数值。举个例子,一个文件被连接了两次(硬连接),这个文件的计数值是3,而无论通过3个文件名中的任何一个访问,效果都是完全一样的,但是如果删除其中任意一个,都只是把计数值减1,不会删除实际的内容的,(任何存在的文件本身就算是一个硬连接)只有计数值变成0也就是没有任何硬连接指向的时候才会真实的删除内容。
  • 软链接(symbolic link) ln-s
    • 我们把符号链接称为软链接,它是指向另一个文件的特殊文件,这种文件的数据部分仅包含它所要链接文件的路径名。软链接是为了克服硬链接的不足而引入的,软链接不直接使用inode号作为文件指针,而是使用文件路径名作为指针(软链接:文件名 + 数据部分–>目标文件的路径名)。软件有自己的inode,并在磁盘上有一小片空间存放路径名。因此,软链接能够跨文件系统,也可以和目录链接!其二,软链接可以对一个不存在的文件名进行链接,但直到这个名字对应的文件被创建后,才能打开其链接。
      关于最后一章的死锁检测,由于具体的算法已经给出,实际上只要在每次上锁解锁的时候进行一些处理即可。

总的来说,rcore的文档可以说非常丰富,可以学到很多,但就实验来说,其实和文档脱节比较厉害。同时如果只是为了完成实验实际上并不需要对rcore了解太多,等之后有空看看mit6.s081是怎么做的,是否在实验编排上有所区别。

开端

原是学安全的,在学习二进制的时候对底层产生了兴趣,看到了这个训练营,刚好学习新的语言的同时,还能巩固操作系统知识。此外鼠鼠快找工作了,希望简历上也能多一个说的过去的项目。

rust start

第一次接触rust,之前都是用C/C++居多。

首先是进行了一系列的语法学习。英文不太好,啃起来比较吃力,所以主要还是看的中文资料。

然后就开始做 rustling。前面的题,还是相对容易的,到后期理解起来还是有些吃力,经常编译通不过。(解决方法就是多看报错,以及求助人工智能)。最后10题是一些基本数据结构题,并没有想象的那么难。

和C++相比Rust的包管理简直太方便啦。之前听闻rust,说它又安全又快,实际学下来,所有权、借用和生命周期之类的概念,确实能很好的防止内存安全问题。而且没有C++那种臃肿(但看起来不太实用)的感觉。确实值得学习。(但是貌似现在工作岗位还不多?)

虽然通过了所有的题,但是感觉并没有完全的熟悉rust开发,还需要持续的写代码和学习。

未来工作

由于还在忙别的事,因而基本上隔几天以后集中突击一下,希望之后能够平均的分配一下时间。每天都学一点。每天都写日志好好的总结。rust需要持续学习,多多使用。抓紧学习RISC-V。紧跟第二阶段进度。

作案动机

期望对操作系统内核有一些基本的了解

第一阶段总结

主要是rust语言的学习

Rust的宏比C的宏友善太多了,C就好比是老师傅的工具箱,而宏就是老师傅的独门绝技,属于是将简单的功能玩出花来。在C中使用宏一般是对一些漏点做弥补,其中就不乏很多Hack的写法,这些写法我也喜欢写,它也着实能解决实际的问题,但也只限于写起来爽,后续的维护和升级都要付出巨大代价。我这一阶段忙也就是因为手上的项目有大量宏相关的内容要更改。在Rust中,部分C需要宏实现的功能被原生支持,虽然Rust中宏也有跟C宏替换所导致的同样的问题,但总体上来说是好上不少的。

RISC-V

虽然有过写RISC-V汇编的经历,基本上是C到汇编的codegen模块,但也是东拼西凑没怎么系统化的,这是我暴露出的一大漏洞。目前对于RISCV体系架构处在一个能领略但不精的状态,希望能在后续随着实验好起来。

2024春开源操作系统训练营

第一阶段总结

引言

很早之前就听说过rust,但是一直没有机会专门去学习(其实是懒哈哈哈),通过朋友了解到thu的这个开源os训练营项目是基于rust的,一下子就来了兴趣,正好最近在学习操作系统的知识,干脆就一起学了吧!就当是给自己的一个鞭策啦!虽然做的比较慢,但是很庆幸自己还是把rust的基础语法过了一遍,但是一些细节可能需要在实践中深入学习掌握。下面简单介绍一下学习的过程。

小白的日常记录 比较简略了哈哈哈

参考资料

群里有很多人已经给出了学习的参考资料,这里推荐一下我用到的:

  • Rust程序设计语言
    课程就是按照这个进度来讲的,rustlings也基本是这个顺序,所以我主要看的就是这个
  • Rust语言圣经
    很火的Rust语言学习资料
  • 通过例子学Ruts
    demo比较多,注释也很详细
  • 大语言模型(ChatGPT, Kimi, …)
    4202年了,相信AI能帮你在入门阶段解决很多问题!

学习总结

有其他的高级语言的基础,Rust的基础语法学起来其实挺快,本人平时使用C/CPP和Python较多,所以在学习Rust的时候下意识会对比类比这些语言的特性来学习。
Rust总体给我的感觉还是比较惊喜的,它确实省去了程序员的很多心思。C/CPP是那种给予了程序员足够的自由,什么都让程序员自己来管,但出了事也得是自己哼哧哼哧debug,比如我指针乱指都能编译通过(点头哈哈哈),自由但费神;而rust直接在编译阶段就给我喊停了,程序员必须符合它的要求来code,语法上做了限制,但是同样的,也就意味着更安全。

  • Cargo是rust的一个比较大的特色,比起cpp中使用cmake来进行包管理,cargo在我看来要更轻松一些。
  • 内存安全:Borrow和所有权系统
  • 并发:std::thread和std::sync::mpsc,避免了常见的并发bug
  • 模式匹配:match、if let和while let
  • 错误处理:Result和Option
  • 生命周期:表达引用的有效范围
  • 宏系统和各种类型:像枚举和各种trait

anyway,总之我觉得rust是个蛮不错的现代语言,来日方长,一步一步接触学习。

个人情况

目前是大三,未来打算搞系统,目前的话,比较钟意的是OS领域,,因为系统的其他方面,就是并行与分布式这块还行,其他的都过于小众了(bushi),所以当时找到了这个训练营,感觉非常的贴合,就报名了。

For Rust

不得不感慨,Rust确实难绷。。我可能也知道了一点Rust为何以安全性著称了,,,,太复杂了,各种约束和检查,让人想死。。

俗话说得好,C是运行时想跳楼,Rust是编译时想撞墙。。。

最大的体验是在写数据结构和算法的10道题。。。思路都很简单,然后常常为了语法错误而搞半天。。再次感受到了C的不负责态度。。

这10道算法题如果用c,大概就是几分钟一道。。但是在这,平均一道都是半小时往上,原因还是在于对其语法的不熟悉。。天天给我报编译错误,我真的麻了,但是熟悉了之后,发现哦原来是这样。

同时Rust的很多特性确实也让我感觉到了其为何安全(代价就是编码的程序猿会死),不过总得来说,确实是一门非常特别的语言。

一阶段学习收获

印象深刻的几个点:

首先是在牵扯build.rs来构建环境变量的时候,可能是我的环境的问题还是怎么着的,基本可以确定是已经实现了,但是仍然不过,而且貌似评测的有bug,会莫名的通过,然后又不通过,很迷茫。

然后是算法题的调了老长时间,,,,没有实现Copy特征,,这个问题真的难受,,泛型的使用真的需要再多做练习和学习。后面看了很多别人的博客,,发现把Copy特征提高一级,改成Clone特征的约束,然后再需要传递的地方改成.clone()就过了,,,难绷

rust的很多的stl和模块化编程也非常的强大,让我看到了强大的解耦合能力和组件化的能力,可以根据编译选项和参数的限制来实现条件编译,在项目实战的时候能带来很多的便利。

Rusiling

确实是折磨人的好题。。。太折磨了

因为题目太多了,所以就不放上做题或者说学习过程中的笔记了,只做一个总结。

留在最后

最后的话,想对未来的自己push一下,五一马上要到了,不打算出去了,直接图书馆走起,越学越觉得自己菜,越学越觉得需要干的事越多,如果运气好的话(希望,,,但是真渺茫)能在9月解放,大概率是奋斗到12月份了

目标的话是完成训练营的三个阶段吧。

第一阶段 Rustlings 总结

第一阶段做的事就是 70-80% 刷 rustlings,剩余时间复习Rust语法知识,翻看Std Doc 和复习了算法知识/(ㄒoㄒ)/~~,总是会忘记细节😂
其中

参考资料

做题中值得注意的点有以下方面:
  • String主题的练习中,&str和String类型的互相转换
  • Iterator中许多方法使得代码更加简洁,如fold, map, map_of, filter等,官方文档续多看
  • 智能指针这块也值得注意,RC, Aec RefCell等
  • 除了以上基础语法方面的内容外,通过手动实现链表, 双向链表, 堆栈, 深度优先和广度优先算法, 排序算法等增进对Rust的进一步理解

第二阶段 rCore

第二阶段从操作系统的发展历史的循序渐进的讲解操作系统的开发,并逐渐加入文件系统、进程。

在这几章的学习内容中,本阶段较为不熟悉的是文件系统这快内容,通过不断研究文档,熟悉代码,研读V3文档,逐渐对rCore加深了认识。

想起一句流传甚广的话”源码面前了无秘密”。

共勉!!!

第三阶段 R4L驱动和跨内核驱动框架设计与实现

本阶段主要时熟悉了R4L, 并在此基础上实现了Print模块、Misc设备驱动模块、树莓派GPIO驱动模块等的开发。
对Rust在Linux体系的驱动开发加深了进一步的认识。
在此基础上熟悉了跨内核驱动框架的设计与实现。
值得说明的是以上皆基于Qemu进行操作。

艰难的Rust学习之旅

自己是在偶然的情况下,在一个计算机体系结构群里发现了这个训练营,当时一看到这个训练营还以为是谁混进来打得一个广告,点开仔细一看,发现
并不是像我想的那样,而是一个非常正规的训练营,而且还是我感兴趣的方向——OS,我立马下定决心,一定要参加,我做到了,然后……就是痛苦的
rust学习之旅了:(
rust和我以前学的语言都不是很相似,这种感觉当我发现rust中变量默认不可变时候就一直缠绕在我的心中,但是这还只是rust众多特性中最好理解
的一个(悲),所有权问题和生命周期问题曾今困扰我很久(虽然现在也不是特别懂……),小小总结一下所有权和生命周期吧:
所有权:是为了解决内存申请与释放问题而采取的一种有别于其他编程语言更热衷使用GC和手动管理机制的特殊管理机制,通过编译器在编译时候
根据一系列预设规则进行检查来确保内存的安全。而这一系列规则中最重要的一点规则是:
Rust中每个值都只能被一个变量所拥有,而当所有者或者说变量离开作用范围时,这个值将被抛弃(drop)

生命周期:生命周期简而言之就是引用的有效作用域,主要作用是为了避免垂悬引用,而生命周期的标注主要是为了帮助编译器进行借用检查的分析
需要特别注意的是,生命周期的标注并不会改变任何引用的实际作用域
rust 中其他的几个非常重要的概念有:智能指针,迭代器,Unsafe,这几个概念也是非常的令我头疼,rustlings做到相关的习题时,老是卡个半天,
但是这些都是rust学习中必须要掌握的重点知识,所以我也是花了相当多的精力在于编译器斗智斗勇中(
rustlings 最后10道算法题也是把我折腾的够呛,写的时候压根就无法关注到它的复杂度,能通过测试就很不容易了:( , 而且后面几道题需要频繁
调用标准库中的方法,我也是找个半天,看来以后还是得多用才能熟悉的写啊
但是不管怎样艰难,我最终还是坚持写完了110题,rust虽然不能说学会了,但是至少入门了吧,那现在就让我继续向操作系统进军吧,加油!

学习rust感觉最难的还是所有权机制和每次在前面要加上的标识,
还有各种API,初学很难记住
以后还得多复习rust

前言

之前听说并且尝试过rust,但是,因为其陡峭的学习曲线,第一次学习失败!在这第一次的时候连蒙带混地走了一遍rustlings,但是依旧对很多语法细节不理解。

对于risc-v,因为他的开源性质,对他很感兴趣,赞同他是指令集中的Linux。并且其简单优雅的设计,让我不必忍受x86的各种复杂和历史包袱也能入门学习OS。

对于OS,之前只是看过理论教材,但是对于具体的实现并不清楚,想通过一门实践课程来丰富自己的实践经验,让理解落地。我认为,学习理解了操作系统之后,计算机便祛魅了很多(除了硬件层面),思考问题可以一眼想到底能够让设计更加灵活,思维更加创新。

过程

这次再次学习rust,重点去理解了生命周期的概念,主要是通过官方的the rust programming language以及查阅std docs来学习。

rust有很多现代语言的特性,并且融合了很多函数式语言的特点,之前热衷于lisp语言,因此对于rust这种做法有好感。

但是,尽管做完了rustlings,因为缺乏更多的工程实践,我认为自己的rust灵活运用能力仍然欠妥,对于rust的所有权机制仍然会有所不适应,仍然以c的眼光来思考编程。

此外,我觉得rust有些过于繁琐,这种保证内存安全的方式真的是最好的吗?对于我来说,这种限制极大影响了我目前的编程思路(可能来自c的编程思路本身就是不内存安全的),
以及其语法,我觉得有些丑陋, 每每看到生命周期就会头昏眼花, 在这里希望zig语言早日能发布1.0(跑

第一阶段做完之后的几周,因为课业问题,迟迟没有开始第二阶段的实践,希望自己能够在此后的过程中调整好自己的时间安排,不慌不乱,有条不紊,最终完成整个训练营。

最后

这次参加本次训练营,有很大的偶然成分,偶然间从某个微信公众号看到消息,但惧于高校的威名,一开始我是害怕报名的(对未知事物本能的惧怕),但是看到开源的字号,想着开源的含义,open to everyone,
以前一直在屏幕后作为观察着的我,一个热爱自由软件,开放共享精神的学生,应该踏出实践的一步,从这样一个课程开始,参与到知识共享的实践中去了(从受益者到贡献者)。

而且,我也很期待自己能够写出自己的一个OS,他可能不够完善,唯一的优点就是能跑,但当我有了这个技术资本,就可以参与到其他的项目(如:Linux)中去了。
也希望能够在这样一个项目中结识到志同道合的朋友,找到属于自己的圈子,提高自己的社交能力。

目录

前言

本着学习 Rust 和 OS 底层相关的想法加入了这一届的训练营。

  • 关于 Rust: 对 Rust 这个语言之前仅仅是略有耳闻, 听说学习曲线陡峭, 也一直没真的了解一下, 所以借此机会学习并了解一下。
  • 关于 OS: 一个方面是虽然写了几年代码, 但是其实对 OS 了解不多, 浅浅的知道一些模糊概念, 另外是对 thu 的 ucore 早有耳闻, 而这个 rcore 同出一源, 因此决定借此机会来学习一下。

由于第一阶段并不涉及 OS 的部分, 因此主要是从 Rust 的学习角度来总结一下第一阶段的内容。

第一阶段使用 rustlings 为评价标准, 提供提示、参考教程、直播讲解、线上答疑等方式组合推进。 我本人没有参与太多直播讲解和线上答疑,主要使用 hint 提示和相关文档、LLM 完成了第一阶段的回答。 因此主要从三个角度来分析所学:

  1. 所有权与类型系统: 这是我觉得 Rust 与其他语言最为迥异的地方, 所以在这里简单阐述一下我的理解。
  2. 做题感受: 对 Rustlings 和 训练营一阶段的一些感受。
  3. 个人反思: 对自己参与一阶段训练营和学习 Rust 的一些反思。

所有权与类型系统

Rust 不进行自动的 GC(内存回收), 也不需要开发者手动释放内存, 而是通过所有权来管理内存, 这是一个非常有趣的特点。 其次, RUst 有着与 Java、 C++、 Python等不同的类型系统, 这一点不仅仅体现在一个字符串就会有 String, str, &String 等多个类型上, 也体现在 sturctimplwhere 上。

所有权

所有权是指当前变量值所占据的内存, 归哪个变量所管理(这一句是个人总结)。 这也就意味着, 当一个变量丧失了对值的拥有, 它就不再能使用这个值。

与 Java 和 Swift 使用的引用计数不同, 引用计数需要管理复杂的引用关系, 同一个值可能被非常多的变量所引用, 这导致内存在很多时候难以回收, 甚至在某些时候无法判断 OOM(堆内存溢出) 的具体位置。 –这个是本人亲身经历的一次问题。

虽然由于同一时刻一个值只能有一个所有者这一个概念及编程环境的实际需要带来了很多的额外的复杂内容, 比如借用引用, 可变借用不可变借用等等。 但是不可否认的是, 这让开发者更深刻的了解了堆、栈等程序等基础概念, 也有利于开发者从思维上管理自己程序的运行时。

类型系统

类型系统第一次感觉奇特是在于 structimpl 的分离。 与常见语言中每个 class 与他的 method 耦合在一起不同, Rust 中方法是对 struct 使用 impl 构建的。

其次是对于 Stringstr 的类型, 让人区分堆与栈, 又或者说, 当明白了一个结构体会被分布在堆还是栈上的时候, 也就不会再纠结于到底是 String 还是 str 了。

做题感受

由于 Rustlings 主要是通过做题来驱动, 因此通过第一阶段训练营意味着完成所有的 Rustlings 练习题。 这样操作的好处是, 可以了解 Rust 的基本语法和编译器, 学会阅读 Rust 的文档和教程等内容。 因此夏令营的学习还是依赖于自我的驱动(当然, 学习编程可能没有那么多的技术热情, 但是确实应该学会自我驱动来跟上新的技术, 跟上时代的脚步)。

但是 Rustlings 存在一个很大的弊端, 似乎是通过对应名称的文件能否顺利执行来判断是否通过的, 也就是可以通过修改不应该修改的代码来使得练习通过。 在练习一开始的时候, 我按照编程习惯和编译器提示懵懵懂懂的过了十来道题, 中间可能修改了 assetequals 等内容。 同理, 如果只是想速通、进入第二阶段等, 完全有很多稀奇古怪的方法可以在不完成解题的情况下进行。

而要解题, 其实也并不需要一定看教学视频(当然这里的含义并非视频或直播不好), 而是 Rust 的编译器可以完成一些基础的提示, 其次是通过 hintReadme 和 代码中的注释可以获取到很多关于对应知识点的信息, 能完成接近于 90% 的问题, 因此靠自己也同样能完成很好的 Rust 学习, 并不需要等待直播开启。

当然, 依然有约 10% 的问题可能难以解决, 这时候利用诸如 ChatGPT、 ChatGLM、 BaichuanAI 等 LLM 可以解决剩下的9% 的问题。 通过提示词优化可以解决几乎 Rustlings 中 100% 的问题。

因此总结下来, 第一阶段使用 Rustlings 来作为评价标准, 是因为 Rustlings 更多的是一个强自驱的学习过程, 需要对自己的学习质量和学习内容有着一定的自我要求。

个人反思

尽管在几天内完成了全部的 Rustlings, 比不过训练营当天秒通的那些人, 但是鉴于我本人并没有 Rust 基础, 所以倒也没什么气馁或难受。

在学习过程中还是对 Rust 有了一点点浅薄的了解, 对 Rust 的代码不再是一知半解或者完全看不懂的情况, 这是一阶段学习后最欣慰的事情。

但是 Rustlings 并不能算是一个全面的 Rust 学习指南, 更多的是一个学习入门的指引, 对于很多的概念比如智能指针过程宏都是浅尝辄止, 需要自行补充更多的学习内容来进行增强。

其次是对于 AI 的使用也会导致个人思维的怠惰, 对于部分题只要求解出来而忽视了解题的思路(比如算法题链表和堆)。 这种只能适用于一时的情况, 不利于长期的学习。

总结

整体总结下来, 训练营选择 Rustlings 还是一个非常不错的决定, 不像是传统课程一般强制直播那样干涸, 也不会是纯练习那样放飞。 而且也成功的体会到了 Rust 的好玩之处, 和他的陡峭艰难, 期待二阶段可以顺利的使用 Rust 写出 Rcore, 对自己交出一份满意的答卷。