自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(11)
  • 收藏
  • 关注

原创 Paxos Made Simple | 论文注解

原文的推导思路比较跳跃,初读会比较难以理解,每个词都能看懂可还是不知所云,我觉得这种阅读的重点应该放在作者的行文动机上,如果能够随时思考“为什么要引入这个命题或者设计上”,读起来就顺畅了,还会留下一些启发式的思考因此本文的写作目的还是帮助理解原文,有关算法细节我会略写之前的工作中,我感觉到读论文得到的思考,没能成体系的记录下来,边啃原文边用 obsidian 记笔记的方式还是效果不好。

2026-01-31 20:49:19 550

原创 【实验笔记】2025 MIT6.5840 | Lab3 Raft

之前提到,上层业务调用的函数尽量要封装好,这里就派上用场了,尽管改变了底层的逻辑,但上层调用的都是 BoardcastHeartbeat() 这样意义明确的封装函数,只需要略微改动中间层函数的内容即可,也利于单元测试和Debug。处理 RPC reply 时,要处理很多的边界case,因此需要进行很多 if 判断, 我选择将这样的判断封装为谓词,命名为IsMatchPrevLog(),这样以Is...()为格式的函数显式标注谓词,这样做进一步提高可读性。

2025-11-07 23:23:38 762

原创 【实验笔记】2024 CMU15445 | Lab2 B+Tree

这种设计,要求设计对象成员时,必须精确到字节,这里倒不是难点 真正的难点在于,我们通过 P1 的存储 API 进行磁盘交互,必须准确维护 page 对应的闩锁与引用数目。可以采用乐观锁机制进行优化,因为发生树结构变化的操作非常少,我们可以先一路获取读锁,只在 Leaf 用写锁,如果检查到有结构变化,再回来一路获取写锁。一方面是人少,另一方面,我觉得在反复推翻尝试后,迭代出的顶层设计,更有利于思考线程间的交互,也就自然写出高质量的代码,这是我从本实验中收获的实践。

2025-11-07 23:22:59 738

原创 【源码分析】xv6 | VII. 总览

如果能真正在头脑中运行这一串程序流,不需要弄清每个细节,只需剥开洋葱,在层层抽象间反复横跳,我想对 xv6 架构就认识的足够了,这也是做源码回顾的动机。而 create 移动到对应的 path,调用 ialloc 获取 inode 资源,再将索引 link 加入到目录文件下,完成空文件创建。此时,uart 检测到串行接口的寄存器发生改变,认为用户发起了一次写入操作,向 PLIC 提出一次设备中断。此时切换到新进程的 forkret,调用 userret 回到用户态,顺利完成进程调度。

2025-11-03 19:58:32 778

原创 【源码分析】xv6 | VI. 文件系统

buffer 为上一层提供了读写封装,用户只需要调用 bread/bwrite 即可,与磁盘的 IO 交互是透明的 注意这里,每个 buffer block 可能会面对多个进程的并发读写,因此需要锁控制,可以采用类似之前 kalloc 的方法,利用哈希映射减小锁粒度。这节我们分析了整个文件系统的层级结构,理解 xv6 是如何将磁盘 IO 进行不断的抽象封装,进而实现精简接口的,认识到每层封装的目的性,这是最有价值的部分。

2025-11-03 19:58:02 939

原创 【源码分析】xv6 | V. 驱动、锁

以 kalloc 链表为例,多个进程同时申请内存时,会在锁上面产生冲突 此时我们可以选择将 pid 哈希映射到多个子链表,为每个链表分别维护锁,这样不同的进程就可以在两个不同的地址同时运行 kalloc ,当哈希不平衡时,我们也可以夺取其他线程的锁,或者重新分配资源。总之,以上代码构成与控制台交互的整个逻辑,consoleinit 设置 console 作为设备抽象的读写函数,并调用 uartinit 完成硬件的初始化配置,而 printfinit 只是设置 pr 锁。

2025-11-01 03:18:17 334

原创 【源码分析】xv6 | IV. Trap、Syscall

在 user 中插入 kernel 的映射,就不需要大费周章地更换页表,直接换权限,运行kernel代码就好了 在 kernel 中插入 user 的映射,就不需要两头跑 copy 信息,直接读出 user 的内存即可 这种设计明显可行,因为虚拟内存是无限的,我们稍微加一点限制,将 user 和 kernel 的映射强制分区,便可以在同一张页表里映射两态的空间。在 III 中,我们提到过,无论是内核还是用户,都会将虚拟空间的顶部映射为 TRAMPOLINE,实际就是用于 trap 的代码。

2025-11-01 03:17:22 688

原创 【源码分析】xv6 | III. 虚拟内存

内核页表的映射,会将 PTE_U 置为禁止用户访问,防止用户通过漏洞恶意访问内核地址 举个例子,一般我们会将页表存入 TLB 缓存,方便读取,如果切换回用户态时,忘记清理 TLB 缓存,那么用户就能通过过期的kernel 映射,直接访问到内核的真实物理地址。fork 时,我们当然可以现在一股脑把物理地址的内容也复制过去,但也有更好的做法 由于 va 机制是基于映射的,可以在映射上面做手脚,让两个不同的 va 指向同一块物理地址,真正写入时再进行区分,这就是 copy-on-write 的思想。

2025-11-01 03:16:49 421

原创 【源码分析】xv6 | II. 进程管理

这样的设计为进程提供了独占 CPU 的假象——swtch结束后,寄存器等资源不变,程序会从之前 trap 的地方继续执行,整个调度过程对用户完全透明。每个进程都是 init proc 直接或间接 fork 得到的,这也是我们在 I 中称其为 “dummy porc” 的原因,它是所有进程的祖先。swtch 切换了 %ra 寄存器的内容,改变了 ret 的返回地址,因此结束后 CPU 会在新进程上运行。xv6 的进程资源是预先分配的,我们会维护一个固定的 proctable,根据状态来分配资源。

2025-11-01 03:15:37 365

原创 【源码分析】xv6 | I. 启动与概览

因此我决定重读一次 xv6 ,一方面是为了复盘项目,捋一遍 OS 设计的 best parctice,另一方面,也是通过产出文本的手段来丰富个人博客,准备面试。但是我们也必须假设有恶意用户的存在,需要对资源进行保护,只有 kernel 才能操作敏感资源,这就是 系统调用 的想法。我们为用户进程提供独占 CPU 的假象,透明地进行 CPU 调度,保存进程的执行上下文,这就是 进程管理。用户编写的程序,应该是面向 OS 接口的,我们向外提供的 API 就是他们与系统交互的唯一方式。

2025-11-01 03:14:29 423

原创 00000

null。

2025-02-20 09:04:15 109

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除