0%

2024秋冬季开源操作系统训练营第三阶段总结-shj

Submit Blog

rcore-blog 这个 repo 已经挺大的了,网不好的 clone 下来还挺费时间的。

实际上可以直接在 Github 上写东西提 PR 不需要本地 clone 下来,Github 网站本身就提供了这样的功能。

打开 rcore-blog 项目主页,在绿色按钮 Code 左边有个 Add file 的按钮,可以直接用 Create new file 写所需要的 Blog 或者用 Upload files 直接上传写好的 md 文件。

需要注意的点是要切到 rcore-blog/source/_posts 这个目录下,不然文件的位置不对。

虽然直接在网站上写,文件里的内容还是要注意一下加上 Blog 需要的分类/标签/作者信息等,这些东西随便打开一个 md 文件复制一下就行。

缺点是数学公式支持和插入本地图片可能麻烦点。

注意一下 Commit changes 里上面是 Commit message, 下面只是辅助描述,一般只用改上面就行。

引用了我很喜欢的一个库 ansi_rgb, 秒了。

hashmap

在 axstd 里开个 mod collections, 再引入 hashbrown, 秒了,

alt_alloc

测试里实际上没有用到 Page alloc 的接口,写完 Byte alloc 就通过了。

rename and mv in shell

有意思的来了,实际上 fs::ax_rename 没有很好的处理 ‘./‘ 和 ‘/‘ 这些前缀后缀。

我认为在 shell 的逻辑里处理文件访问文件名是一个错误的抽象,因此我写的时候决定不在 shell 代码里处理路径问题。

观察到 ls 命令可以处理前缀后缀,一路跳转后决定在 modules/axfs/src/fs/fatfs.rsDirWrapper::rename() 中进行处理,刚好旁边就有 remove 方法可以参考。

lab1

觉得没意思就没写,看群里大佬们玩挺花的,我自己想能不能玩点 hack, 最后确认到 main 地址是可以获取的,main 的 text 内存是可读可写的。

也就意味着可以整花活来跳转到自定义的 main 函数当中去,但是想到这样就要做 platform 的适配,感觉工作量并不小,就没整。

set populating to false

AddrSpace 为入口开始找参考的辅助函数,发现直接就有 handle_page_fault 可以用,一调用就过了,看看 m2 的参考才知道 user flag 的作用。

mmap

这个练习用到的 api 挺多,需要找找 find_free_area, api::fs, LinuxError, AxError.

因为 rust 没有 goto, 所以错误处理需要包一层 fn() -> Result, 这样才能用 ? 来减少代码量。

? 只能在 ResultOption 上用就已经很强大了,如果 try_trait_v2 稳定了都不用包一层 fn 了,不敢想象有多爽。

simple hypervisor

这个练习不错,有一定难度。

首先处理 csrr a1, mhartid 这条指令。

尝试了下直接用 asm!("csrr {rd}, mhartid", out(reg) rd) 进行代理,不过如我所料的是 hypervisor 也没有 M 权限,所以不能这样弄。

但是可以注意到 mhartid 的语义是 cpu id, 所以可以直接用 axhal::cpu::this_cpu_id() 的值就行。

不过事实上根据语义应当返回的值是 vcpu id, 也就是 hypervisor 让 Guest 看到的 cpu_id, 但是我懒得添加相关的逻辑了。

把值写到上下文的 a1 寄存器之后需要把 spec 也加上指令长度。

然后处理缺页,注意到 src/task.rs 里有 TaskExt 的定义,并且压根没用上,可以知道大概需要用上。

但是我偷懒没去用,而是直接改了 vmexit_handlerrun_guest 的接口,加一个 uspace 参数,这样就能在 vmexit_handler 里修改页表了。

对于一个内核来说,所有内存地址都是可以访问的,所以直接用 uspace.map_alloc() 就行了,权限可以全加上。

一个很有意思的点是 hypervisor 寻址用的是 satp, Guest 机器寻址用的是 hgatp. 所以写入用 uspace.write 来进行。

Emulator mode device

直接把注释去掉就能通,所以改起来挺简单的。把 populate flag 置为 false 会导致 Supervisor Page Fault 错误。

刚好文件里就直接给出了一个 load_vm_image 辅助函数,直接拿来用把参数改改就完成了。size 可以通过 fs::metadata 来获取。

之前提到过 aspace 目前不支持 File 类型的 Backend, 不然就可以把 populate 置为 false 了,会快上不少。