Rust语言学习
Rust 编程语言是一个专注于安全、并发和实用性的系统编程语言,语法简洁先进
内存安全:无需垃圾回收器即可保证内存安全。
所有权系统:所有权、借用和生命周期是 Rust 独有的特性,用于在编译时管理内存。
类型系统:Rust 拥有强类型系统和类型推导。
并发:Rust 通过所有权模型来避免数据竞争。
构建系统: Rust拥有强大且易用的构建系统和包管理器cargo
第三方库: 强大的生态系统支持,可以找到几乎任何类型的库。
学习资源丰富,做完Rustlings的一系列小练习可以了解rust的各个方面,有官方中文文档
rcore
课程很硬核,实验较简单
实验一
实验一让我了解了rcore基本的进程调度实现,以及RV64汇编语法,寄存器特性,调用约定,RISC-V的指令集很简洁,总共就100多条指令.
实验二
实验二让我了解了以下内容
SV39分页机制: 开启SV39分页后所有的内存访问都变成虚拟地址形式,通过MMU将虚拟地址转成物理地址
rcore内存管理: rcore为所有物理地址做了一个恒等映射,可以通过虚拟地址访问所有物理地址,先实现了一个分配物理页帧的
FrameAllocater
,然后实现了一个MemorySet
来实现分配地址空间和地址空间对应的物理内存双页表OS: 系统为用户态专门设计了一张没有内核模式代码的页表,内核模式区域只包含了trap入口代码,用户态发生trap就跳到Trampoline切换到内核态页表,内核态返回用户态的时候又切换回用户态的页表,这样子做每次trap会多出两次切页表导致TLB清空的性能消耗
为了防范可能出现的类似”幽灵熔断”漏洞的攻击,牺牲一些性能来换安全性还是有必要的.
实验三
实验三学习了rcore的进程管理机制,fork,exec的实现,Elf映射到内存的过程,以及支持进程优先级的stride调度算法
fork: 按照一个父进程创建一个子进程,子进程拷贝父进程的地址空间
exec: 清空进程的地址空间来执行新的可执行文件
stride调度算法: 支持优先级的进程调度算法
原理是给每个进程添加priority和stride的成员,调度器每次都挑选stride最小的进程来执行,进程执行一个时间片就加上一个大常量BIG_STRIDE除以priority的值
priority要求必须>=2,因为如果=0的话除法就会发生异常,=1的话就不支持溢出处理,>=2的情况下STRIDE_MAX – STRIDE_MIN <= BigStride / 2
,这样可以做溢出判断
实验四
实验四学习了easyfs文件系统的实现,这个文件系统可以以模块的形式添加进内核里.
这个内核模块的开发流程可以在用户模式做测试,测试稳定之后放到系统内核里面,这样子做有很多好处
- 让内核设计更模块化
- 可以把这个文件系统模块放到用户态,如果以后要实现一个用户态解析这个OS文件系统的工具,比如ch6中的
easy-fs-fuse
可以在测试环境的用户态生成一个fs.img给虚拟机内的操作系统使用
easy-fs的实现:
把磁盘的线性空间分块,每个块大小为常量BLOCK_SZ
第一个块的信息是超级块,包含文件系统的标识,大小,inode区域,数据分布信息
inode用来描述文件和目录,根目录的inode编号是0,相当于linux中的/
根目录,通过根目录来实现索引文件系统中的所有文件