第二阶段总结
学习感受
- 在参加rCore训练营之前,对于操作系统的相关知识我是比较模糊的,在平时的编程中往往只是简单用到一些比如协程、多线程、原子计数、互斥锁等等编程语言提供的编程模型,对于其内在实现基本一知半解,而在这次阅读了rCore相关教材之后,对这些函数背后所隐藏的机制有了更深的了解。在训练营的过程中,因为之前有用Rust经验,所以第一阶段Rustlings能够比较快速的解决,但是到了第二阶段,因为对于相关知识比较陌生所以做的比较慢一些,unsafe Rust、risc-v汇编这些平时接触非常少,所以在阅读相关代码的时候要查阅较多资料。目前虽然完成了第二阶段晋级的目标,但是感觉前方未知的领域更加宽广。
- rCore依托于Github的授课方式也让我大开眼界,第一次知道Gihub Classroom这个服务,老师们围绕OS的学习建立的这一整套学习方式(Github Actions、排行榜、直播课网站),不仅仅局限于书本,把计算机专业和教学的完美结合到一起。同时rCore的社区感觉也已经很庞大了,已经有许多人做出了自己的贡献,虽然我目前还没有厉害到可以给rCore提PR,但是希望以后可以。
学习总结
- 其实我学习Rust的开端比较早,就是看到各大视频网站有很多关于Rust如何安全的宣传视频,当时也没有适用场景和刚需,单纯出于好奇就开始了自学,在学完之后也就仅限于用来做一些比如Advent of Code的编程题,但是其间经常由于Rust严格的检查而被Rust折磨🤣。rCore把Rust用到了系统级的编程领域,难度更是加大了,因为要理解这些代码,首先要理解其背后隐含的OS设计思想,这些就是我对于Rust学习的感受。
Lab总结
Ch3 Lab
第一次做OS相关Lab,在起步时熟悉整个代码框架是比较重要的,这样在做题时才能找到相关的接口,Ch3 lab主要关于task info的获取,需要编写函数来获取每个task的相关信息。
为TaskControlBlock增加field
- start_time: usize
- syscall_count: [u32: MAX_SYSCALL_NUM]
os/src/task/mod.rs
- 为TaskManager实现syscall_count_increment()
主要逻辑:- 使用match来匹配syscall id,从而决定增加conut的对象。
- 并在trap_handler中调用。
- 在run_first_task()中使用get_time_ms()获取当前时间
- os/src/syscall/mod.rs
- 为TaskInfo实现reveal()
主要逻辑:- 计算运行时间
- 从Task Control Block中获取task info
在sys_task_info()调用
Ch4 Lab
在初读关于内存空间的内容时经常一头雾水,各种术语经常忘了意思,需要经常翻速查表、文档和笔记。
因为地址空间的跳转,所以之前的trap的实现也要修改。
- os/mm/memory_set.rs
- mmap
- 将vpn与ppn关联,从遍历整个VirtualPageNum,若已存在对应pte,则返回失败,若不存在则分配ppn
- munmap
- 将vpn从page table移除
- mmap
- os/syscall/process.rs
- sys_get_time()
- 用 translated_byte_buffer 将用户地址转换为对应的物理地址,然后读取TimeVal大小的内存
- sys_task_info()
- 同理先转化为对应物理地址,然后读取TaskInfo大小的内存,就可以获取task_info
- sys_get_time()
Ch5 Lab
Lab 5实现spawn和stride调度算法,spawn一个子线程需要创建一个新的TaskControlBlock,然后再push到当前任务下
os/syscall/process.rs
- sys_spawn()
- 首先获取app data(get_app_data_by_name), 再根据data生成新的task
- sys_get_priority()
- sys_spawn()
os/task/manager.rs
- 实现stride算法
- 对TaskManager的ready_queue进行迭代,使用min_by_key()找到当前最优先的TaskControlBlock
- 实现stride算法