从零编写操作系统 20 - ATA PIO 块设备:把扇区读成可信的数据
第 19 篇的程序仍然来自内核中的 ELF 字节数组。即使磁盘镜像已经装着启动扇区、第二阶段和内核,保护模式内核也不会读盘;它只能使用启动阶段提前搬进内存的内容。下一篇要解析 FAT16,本篇必须先建立一个更窄的基础:给定一个合法 LBA,可靠地取回恰好 512 字节。 本篇增加 primary master 的 ATA PIO 只读驱动。它用 IDENTIFY 取得设备容量,用 READ SECTOR(S) 一次读取一个扇区,区分参数错误、设备错误和等待超时。命令已经发出后若状态序列失效,通道会进入失败状态;在实现复位协议以前,驱动不会假装设备已经恢复。 实验实际读取 MBR、LBA 2047 和最后一个扇区 LBA 4095,另用三个独立镜像验证 BSY 不结束、DRQ 不出现,以及 QEMU 对容量外 LBA 的真实 ERR/ABRT 响应。所有镜像都从 BIOS 完整启动,编译成功不算设备实验通过。 BIOS 读盘不能直接变成内核块设备 第二阶段仍在实模式时,可以调用 BIOS int 0x13 把内核搬到内存。进入保护模式后,当前内核没有虚拟 8086 模式,也没有切...
分布式系统 12:Raft 日志匹配与本任期提交
五台服务器里,三台都有同一条日志,是否就可以回复客户端“写入成功”?在 Raft 中,还要看条目产生于哪个任期,以及当前领导者凭什么判断它已经提交。 设 A 在旧任期写入 x,后来重新当选,并把 x 补到了多数节点。另一个节点可能保留着更新任期产生的冲突条目 y,仍有资格在下一轮赢得选举。此时直接提交 x,会把一个允许被覆盖的条目当成不可撤销的结果。 第 11 篇 建立了任期、投票与保存完成后的消息释放边界。本篇在同一个 Go 核心上加入实际日志,解释 AppendEntries 怎样修复分歧,以及“本任期条目获得多数确认”为什么能保护整段前缀。 模型与三个不同的位置 采用固定成员配置、崩溃恢复故障模型和非拜占庭消息行为。消息可以延迟、丢失、重复和乱序,节点不会任意伪造协议内容。多数始终按完整配置计算;五节点需要三个成员。成功确认的持久状态在恢复后仍然存在,是协议安全性的一项前提。 日志条目包含任期和命令,索引从 1 开始。leader 只在自身日志末尾追加当前任期的条目;follower 可以删除与合法领导者冲突的未提交后缀。实验中的命令是字符串,尚未接入应用状态机。 三个位置...
分布式系统 22:协议、协调服务与多数派故障
三成员 etcd 只剩一个成员时,一次写请求等待约三秒后超时。恢复第二个成员,完成新的写屏障,再读取先前请求的键,它已经存在。客户端没有收到成功回复,与系统没有执行该写,是两件不同的事。 分布式系统 21:etcd 的读、事务、Watch 与 Lease 前篇已把读、事务、Watch 与 Lease 的保证拆开。本篇将这些 API 放回协议与实现的完整关系中,对照 Paxos、Zab、Raft、ZooKeeper 和 etcd,并用真实三成员进程故障验证多数派丢失与恢复。协议比较依据原论文;产品固定 ZooKeeper 3.9.6、etcd 3.7.1。三成员实验只运行 etcd,不能把文档对照表当作两个产品都实测过。 协议正确为何仍不足以保证业务正确 Paxos、Zab、Raft 解决复制状态之间如何达成安全顺序。ZooKeeper、etcd 则还包含存储、客户端连接、读写 API、变化通知和运维接口。把五个名字直接放进“谁支持 Watch”的表格,会混淆算法与服务。 协议安全依赖实现保存承诺、任期和日志;产品 API 又决定客户端如何观察结果;业务配方最后还要处理重试、检查...
分布式系统 11:Raft 任期、投票与选举安全
三台服务器 A、B、C 同时竞选。A 得到自己和 C 的票,成为领导者;随后 C 重启,忘掉已经投给 A 的记录,又投给 B。B 加上自己的票,也达到了多数。每次计票都没有算错,集群却在同一轮选出了两个领导者。 问题出在投票承诺没有跨越重启。一次选举能否安全,不只取决于票数,还取决于票属于哪一轮、由谁投出,以及已经回复成功的投票是否还能被遗忘。 第 10 篇 将稳定领导者与多槽日志联系起来。本篇开始构建另一条可累计的实现:先完成 Raft 的选举状态转换,下一篇再加入日志复制与提交。本篇的 Go 核心会继续复用;当前尚不能存储客户端命令,也不提供完整 Raft 服务。 任期把局部观察分开 采用一个固定成员配置,成员身份在实验期间不变。进程可能崩溃恢复,消息可能延迟、丢失、重复或乱序;节点不伪造身份、不发送任意错误内容。多数指完整配置中超过一半的成员,三节点需要两票,五节点需要三票,不能因两台暂时不可达就缩小分母。 每个节点保存自己的 currentTerm,即已经知道的最高任期。任期是逻辑轮次,不是由统一时钟切出的时间段。A 已经进入 term 4,隔离中的 B 仍可能只知道 t...
分布式系统 21:etcd 的读、事务、Watch 与 Lease
Watch 恢复时,保存“刚收到的 revision”还不够。一笔事务在修订 2 同时改了两个键,消费者只应用第一个事件就把续传位置记成 3,重连后会永久漏掉第二个键。服务端已经完整发送,错误发生在消费端的检查点。 分布式系统 20:etcd 的 Raft 与存储路径 前篇区分了 Raft 位置与 KV revision。本篇使用同一官方 etcd 3.7.1,讨论默认读、条件事务、Watch 恢复与 Lease。核心问题是:一次 API 响应究竟证明了什么,客户端需要补上哪些状态管理,才能把产品保证变成正确的业务行为。 默认读与 serializable 读 默认 KV 操作保证严格可串行化,并遵守实时时序。写已经成功完成,随后发起的读不能返回该写之前的状态,除非又发生了合法的后续修改。对于单次读,可以在调用与响应之间选择一个线性化点。与读并发的写可以排在这个点前或后,不能要求返回值包含直到响应最后一刻才完成的所有写入。API guarantees etcd 的默认 Range 先执行 LinearizableReadNotify,再读取 KV;serializable=tr...
Claude Code 源码深度解析:五层架构与核心设计模式
Claude Code 的工程复杂度集中在模型调用之外:工具怎样获得执行权限,长会话怎样压缩,子任务怎样隔离,失败之后怎样恢复。2026 年 3 月暴露的源码快照让这些机制有了可研究的实现样本;随后数月的文档和版本变化,又说明其中哪些抽象保留下来、哪些接口已经改变。 本文核对资料截至 2026 年 9 月 19 日。历史实现以 v2.1.88 的公开研究为边界,当前功能对照官方文档与当天发布的 v2.1.278。五层架构是一种阅读视图,不代表 Anthropic 对外承诺的固定模块划分。 从泄露快照到持续演进的产品 3 月 31 日的 source map 事件暴露了 Claude Code CLI 应用的大量 TypeScript 源码。它提供了客户端运行时的研究材料,不能等同于模型权重、训练系统或全部云端服务的开源。文件数和行数受生成文件、依赖及统计口径影响,分析架构时更有用的是固定版本与调用关系。 社区研究已经从罗列隐藏开关,转向解释执行系统。论文 Dive into Claude Code 于 4 月 14 日提交,7 月 2 日更新 v2;其研究对象仍是 v2.1.8...
计算机图形学 00:从一个像素到一张图像
一张图左右颠倒,错误可能只是一行数组索引;颜色发暗,原因也可能发生在写文件之前。只检查程序退出码,不能判断这两类错误。图形学实验的第一个可用结果,是一张能追查每个色块来源的图,以及一组独立于画面观感的检查。 这个实验生成一张 16×16 的非对称小图。左上、右上、左下、右下分别是红、绿、蓝、黄,内部有黑红交替的竖条纹,绿色分量向下分四级增加,坐标 (3,5) 放一个品红标记。它没有相机、光源或三维模型,全部颜色由整数坐标直接决定。 图为程序输出的 PNG 转换版,以最近邻方式放大显示。放大的方块用于检查样本排列,不能据此推断真实显示器的发光结构。原始数据也可下载:diagnostic.ppm。 像素数组先确定什么 用 (x,y) 给一个样本编号,需要先规定原点与方向。这里原点是图像左上角,横坐标向右增加,纵坐标向下增加,合法范围为 0≤x<16、0≤y<16。这些是图像存储约定,不代表今后的三维世界也必须让 Y 向下。 一个 RGB 样本保存红、绿、蓝三个通道。本篇每个通道是 0 到 255 的整数码值,0 表示相应通道的低端,255 表示高端。红色标记是 (255...
分布式系统 10:Multi-Paxos 与复制状态机
单值 Paxos 为一个位置选定一个值。数据库却要不断处理请求:先设置余额,再扣款,再读取结果。即使每个位置都不会选出两个不同命令,副本按不同顺序执行这些位置,仍可能得到不同余额。Multi-Paxos 需要把逐槽共识、领导者恢复和状态机执行连接起来。 上一篇:多数派交叉与单值 Paxos建立了单值 Paxos 的承诺与选值规则。本篇沿用多数派交叉的证明方法,把共识实例扩展成日志槽。MIT 6.5840 的 Paxos 讲义也通过有序日志连接共识与数据库复制;Stanford CS244B 的课程路线提供复制与容错背景,不将其课程日程当作特定 Multi-Paxos 实现的规范。 槽号与轮号是两个维度 日志槽号 slot 表示命令的执行位置;轮号 ballot 表示一次提案权限的竞争。一个领导者可以在同一轮里推进多个槽,一个槽也可能经过多轮恢复。把它们合成一个递增整数,会丢掉“同一槽在不同轮里接受过什么”的信息。 本篇固定三个 acceptor A、B、C,多数派为两个。P 独占轮号 1,Q 独占轮号 2;两个领导者可以在一段时间内都运行。唯一轮号所有者保证同一 (ballot,...
分布式系统 20:etcd 的 Raft 与存储路径
一次删除不存在键的请求,可以让 etcd 的 Raft 提交位置从 7 增长到 8,而 KV revision 仍为 4。这并不矛盾:日志记录需要按序执行的请求,修订记录实际发生的 KV 状态变化。两个计数器回答的问题不同。 分布式系统 19:ZooKeeper 一致性、锁配方与外部 fencing 前篇已把协调服务的资格判断与外部资源写入分开。etcd 的同类分析还要穿过复制日志、状态机应用和本地存储三层。本文固定 etcd 3.7.1,依据官方文档、固定版本源码和真实单成员实验,解释一次写入如何变成可读状态,以及重启为何不能简单重放整份 WAL。 一个请求经过哪些位置 Raft 日志条目具有 index 和 term。index 表示日志位置,term 标识条目产生的任期;本地保存某条日志不等于已经达成提交条件。提交前缀确定哪些条目可以进入状态机,各成员随后按序 apply,成员之间的应用进度可以不同。 KV revision 则属于 MVCC 状态机。一个写事务实际修改了 KV,才产生新的主修订。内部日志项、不修改任何键的删除、租约元数据操作,都可能消耗 Raft 日志位...
分布式系统 09:多数派交叉与单值 Paxos
A、B 已经接受 X,C 尚未收到消息,提议者又失联了。另一个提议者向 B、C 发起 Y,B 能否再接受?只规定“得到多数票即可成功”,两个值都可能拿到两票。禁止每个节点再次投票也不够:第一轮的票分散后,所有节点可能永久停在不同候选值上。 第 08 篇区分了安全性与活性。单值 Paxos 允许不断发起新一轮尝试,同时限制后续提案的取值,使所有获得多数接受的提案携带同一个值。MIT 6.5840 的 Paxos 讲义从多数派和两阶段进入这一问题;本篇以 Lamport 的原论文及课程精确伪代码为依据,推导约束,并用有限消息调度检查违反约束的后果。 MIT Paxos 讲义。 一次共识的模型和三个角色 本篇只有一个共识实例,成员固定为 A、B、C,法定集合 quorum 取任意两个 acceptor。一般多数派大小为 floor(N/2)+1。进程遵守协议,消息可以延迟、重复或丢失,但不被伪造;进程可以崩溃恢复,持久状态须在恢复后保留。这些约束不覆盖拜占庭行为和磁盘状态永久丢失。 proposer 生成提案,acceptor 持有承诺和接受记录,learner 根据接受证据得知结果。...







