第23讲 · 存储设备的抽象
2026 南京大学《操作系统原理》第二十三讲 · 课堂实录重构
| 主讲 | 蒋炎岩(Yanyan Jiang) |
| 视频 | https://www.bilibili.com/video/BV1RHLh6pEqn/ |
| 课程主页 | https://jyywiki.cn/OS/2026/ |
| 本讲讲义 | https://jyywiki.cn/OS/2026/lect23.md |
| 讲义 / 幻灯片作者 | 蒋炎岩,https://jyywiki.cn/ |
| 讲义 / 幻灯片许可 | CC BY-NC 4.0 |
| 图片来源 | 书中插图为课堂演示与讲义渲染图;演示类截图为视频画面 |
对应讲次:第23讲(南京大学 操作系统原理)
制作模型:deepseek-flash(coding-agent / pi;据 ~/.pi/agent/settings.json)
编者说明:本书由课堂录像的语音字幕重构而成,术语、章节骨架与参考链接已按课程官方讲义(
lect23.md)校准。讲师的口语风格、类比与案例被尽量保留;编辑性的补充一律以「编者说明」或「编者拓展」标出。
引子
(参考时间: 00:00)
进入持久化部分的第二节课——讲一个 bit 是怎么存储的。
回顾 I/O 设备:设备 = Canonical Device Model(总线上的寄存器),从 LED 灯到打印机、GPU 都遵循这个模型;设备驱动程序把 file operations 翻译成设备能听懂的命令(读、写、控制 ioctl)。
编者拓展|DeepSeek 在招「Agent Harness 研发工程师」:讲师开场评论了一份招聘 JD——「除模型本身以外的所有工作,都属于 Harness 的范畴」,要求「能够在 AI 辅助下,在没有直接经验的领域(如语言、技术、框架等)进行有质量保证的编程工作」。「这不就是招 AI 原生时代的超级个体吗?写这个 JD 的人说『这年头还有不拥抱 AI 的学生啊』——传统的学习方法可以说是出生即死亡了。」
正式进入 Persistence:
Persistence: "A firm or obstinate continuance in a course of action in spite of difficulty or opposition."
「我们的祖先就希望数据能永久留存——在石头上刻字就行啦。」
📷 Rosetta Stone:跨越千年的持久化存储——在稳定介质上「挖坑」
回到原视频 (00:04:00)
一、数据的持久化
1.1 正 v.s. 反:磁
持久化可能没有想象的那么困难——「你只要有一个能够反复改写的状态,就能持久化」。就像小时候的磁性画板:六边形格子里是铁粉,磁笔把铁粉吸到上表面就有颜色,底下磁铁一刷就擦掉了。
📷 磁性画板:一个能反复改写的状态(铁粉在格子里的上/下)
回到原视频 (00:06:00)
编者说明:在计算机世界里,为了能让计算机访问,一个 bit 必须能用电路读写——必须能转成电信号并被电信号驱动。理论上你可以给画板加上电磁铁和摄像头来「Persist data」,但那显然不高效。更高效的做法就是「内卷」:把尽可能多的 bit 塞到很小的空间里。
电磁感应:物理和数字世界的桥梁
1D 存储设备:磁带(1928)——在纸带上均匀粘上铁磁体,只需要一个机械部件(转动)定位:
- 读取:磁通量变化产生电动势,放大感应电流;
- 写入:强磁场下电子自旋方向翻转(不是磁针物理翻转)。
📷 磁带:一维存储,用电磁感应读写
回到原视频 (00:08:00)
编者拓展|「磁带密度可以高得离谱」:现代磁带的存储部分只需要结晶(结构比集成电路简单得多),但密度可达 300 Gb/in²(30TB/磁带)。「以前我的小霸王学习机还要插卡带、用录音机把 BASIC 程序录到磁带上……」——磁带作为存储设备的分析:
特性 评价 价格 / 容量 / 可靠性 低 / 高 / 高(固体,放几十年上百年) 顺序读写 勉强(需等待定位) 随机读写 几乎完全不行(这是致命缺陷) 应用场景 冷数据存档备份;音频/视频(只需要顺序读写)
📷 磁带的应用场景:音频/视频——正好只需要顺序读写
回到原视频 (00:16:00)
磁鼓(Magnetic Drum, 1932):1D → 1.5D——用旋转的二维平面(绕成圈的磁带)存储数据,读写延迟不会超过旋转周期(随机读写大幅提升)。
疯狂内卷:磁盘(Hard Disk, 1956):1.5D → 2.5D——在二维平面上放置许多「磁带」(磁道),读写头还有一个自由度可以切换磁道。
📷 磁盘:在二维平面上放置许多磁道,读写头 + 转轴
回到原视频 (00:20:00)
编者说明:现代磁盘是很硬的密封封装,转速可达 5400/7200 rpm;为提升密度,工程师不断改进——垂直记录(磁畴竖着排列)、减小 bit 尺寸、多盘片双面……成本低、容量高、可靠性高,是计算机系统的主力数据存储(「甚至坏了还有可能修」,因为盘片化学性质稳定)。
性能调优:读/写一个扇区时,读写头要到对应磁道(7200 rpm → 120 rps → 寻道约 8.3ms),转轴再把盘片旋到读写头下。用缓存/调度缓解——著名的「电梯」调度算法(「现在这些算法都集成到磁盘控制器里了,因为只有厂商最清楚磁盘的参数」)。
软盘(Floppy Disk, 1971):把读写头和盘片分开——计算机上的驱动器 + 可移动盘片(8″(1971)、5.25″(1975)、3.5″(1981))。
📷 软盘:5.25″ 与 3.5″——把盘片做成可移动的「数据快递」
回到原视频 (00:29:00)
编者拓展|软盘的「写保护」与吉祥物:3.5″ 软盘上有一个写保护小孔——拨下塑料片后,驱动器用一个光电传感器就能知道是否写保护。软盘以 1.44MB 为单位携带数据,「仙剑奇侠传就是软盘发行的,玩到一半它会说『请插入下一张软盘』」。「软盘今天作为吉祥物存在——就是你们软件里那个没见过却代表『保存』的按钮 💾。」
1.2 坑 v.s. 平:光
坑:天然容易「阅读」的数据存储——从 Rosetta Stone 的「挖坑」,到现代工业挖出更精细的坑。
Compact Disk(CD, 1980):在反射平面(1)上挖上粗糙的坑(0),激光扫过表面就能读出信息:
- 44.1kHz, 16-bit, 2 声道贝多芬第九交响曲(74 分钟,~700MB)——飞利浦(碟片)和索尼(数字音频)发明;
- Eight-to-Fourteen Modulation(EFM)编码(8 bit → 14 bit)。
📷 CD:激光读取反射面上的坑;8→14 调制编码
回到原视频 (00:40:00)
编者拓展|光盘最有趣的特性:容易复制:坑是挖在透明塑料上的,压上反射膜——「压盘」:母盘做好后,每复制一张只要压一下。3 秒生产一张 Blue Ray 100GB(33,000 MB/s 写入速度)。
「有个有意思的故事:在两个数据中心之间传数据,把整个数据中心写成磁盘、用卡车拖过去,带宽可能比网络更快。」
Project Silica:回归 Rosetta Stone——用激光在玻璃内部聚焦、改变晶体结构写入 bit(Random read + Append-only write = 任何数据结构),配一个像图书馆一样的机器人来做随机寻址。
📷 Project Silica:在玻璃中「永久挖坑」,用机器人实现随机访问
回到原视频 (00:51:00)
编者拓展|Random Read + Append-only Write = 任何数据结构:讲师插入了一节「数据结构课」——如果你有一个只能随机读、但只能追加写的介质,你完全可以实现任何数据结构,比如持久化二叉树(persistent data structure):修改时把从根到叶的整条路径复制一份(旧的子树指针仍然指过去),代价是 $O(\log n)$,且所有历史版本都还在。「只要拿到那个指针,就知道这是上一次的那棵树。」——这正暗合 Project Silica 与 FTL 的设计。
1.3 充电 v.s. 放电:电
磁和坑都不太完美:磁有机械部件(无法避免的 ms 级延迟);光挖坑效率低、填坑困难。
「完美」= 电子的密度、电路的速度——Flash Memory「闪存」:在电路里「挖个坑」——把电子填进去是一个状态,把电子放跑是另一个状态。甚至可以精确控制电压实现多 bit:MLC(2 bits)、TLC(3 bits)、QLC(4 bits)。
📷 1-Bit Flash Memory:Floating Gate 的充电/放电
回到原视频 (01:02:00)
编者拓展|Jim Gray 的预言(2006):「Tape is Dead, Disk is Tape, Flash is Disk, RAM Locality is King」——在 SSD 还没普及时就预见到 Flash 会取代磁盘。「Flash 全身都是优点……最不讲道理的特点是扩展性:容量越大,速度越快。」
——因为闪存颗粒之间是完全并行的:「你买 MacBook,512G 的磁盘性能比 256G 好接近一倍,因为多一份颗粒就多一倍的带宽。」
开启「优盘」时代(1999):使 Flash 普及的不是高速 SSD,而是优盘——朗科专利「用于数据处理系统的快闪电子式外存储方法」(把 USB 接口和芯片封装在一块电路板上)。
📷 朗科优盘专利:让 Flash 通过 USB 直接接入电脑
回到原视频 (00:58:00)
Flash Memory 有一个致命的缺陷:放电(erase)做不到 100% 放干净——放电数千/数万次后,cell 就好像「充电」状态了(Erase Saturation),cell 死掉,「wear out」。QLC 大约只有 1,000 次写入寿命。
for i in range(1000):
Path("a.txt").write_text(str(i))
「这个文件就该要损坏了?」——但你们从来没遇到过这个问题。
编者说明:物理的限制不可能突破,但可以用软件弥补。「你的 SSD、优盘、甚至是 TF 卡里都藏了一个完整的计算机系统」——有主控 CPU、DRAM、缓存、store buffer、操作系统……
软件定义磁盘:FTL(Flash Translation Layer)
- Wear Leveling:用软件使写入变得「均匀」(虚拟内存)——维护一张 Logical-to-Physical Table(L2P Table);
- 逻辑块 1 这次可能写到物理块 2,下次写到物理块 4……每块都记录写入次数;
- 再一次:Random Read + Append-only Write = 任何数据结构——L2P 表本身就是一张持久化的数据结构,不能是一个普通的 hash table(否则第一项会被写坏),必须用一个 append-only 的持久化数据结构来实现。
📷 FTL:Logical-to-Physical 映射表 + Wear Leveling,把写入均匀分摊到每个颗粒
回到原视频 (01:03:00)
编者拓展|不要买过度便宜的优盘:优盘、SD 卡、SSD 都是 NAND Flash,但软件/硬件系统的复杂程度不同(一个 SD 卡上也有一个 ARM CPU,但 RAM/缓存/算力远不如 SSD)。「设备 = 一组寄存器 → 设备可以伪造」:主控可以改,假 SSD 会伪装成 1TB 但实际只有 64GB——「写超出的部分就直接扔掉,这就是为什么不要买过度便宜的优盘。」
📷 哪怕是一张 SD/TF 卡里也藏了一个完整的计算机系统(ARM CPU + RAM + FTL)
回到原视频 (01:07:00)
二、操作系统视角的存储设备
2.1 存储设备的抽象
Random Access 的代价:寻址——磁盘/磁带/光盘需要物理旋转;电路也需要选通信号 Die → Plane → Block → Page(16KB)。
减少寻址的代价:按块访问:
- SSD Page 内的独立选通信号就是浪费电路——整个 Page 是同步并行读写的;
- 存储设备 = 随机读写的 block array:
struct block disk[NUM_BLOCKS]。
Block devices:按块访问的字节序列(可以直接 mmap 到进程地址空间)。但这个抽象不是没有代价的——不经意间的读/写放大:
如果你
mmap一整个磁盘,哪怕只写一个字节,也要把这一整块读出来、改掉、再写回去——「我写一个字节,甚至你还读了 16KB 的数据。」
📷 存储设备 = 随机读写的 block 数组;映射到内存后一个字节的写也会带来读写放大
回到原视频 (01:12:00)
📷 存储设备 = 随机读写的 block 数组:SSD 内部 Die → Plane → Block → Page(16KB)
回到原视频 (01:11:00)
编者拓展|NVMe ZNS 与读写放大:需要极致性能的场景用 NVMe ZNS(Zoned Namespaces) 直接操纵 append-only 的 Zone。NVMe 2.0 允许不再用 block array 的方式访问设备,而是直接操纵设备内部的数据结构,从而避免读写放大。
2.2 Linux Bio:一个应用程序「看不见」的接口
为你的存储设备实现 struct block_device_operations 和 struct request_queue,剩下的 read/write/mmap 都是文件系统的事了。
编者说明:block device 与 file operations 不同——file 支持任意 offset 读写(用
lseek跳游标),但 block device 要么读一块、要么连续读/写多少块。只要实现「读/写块」,剩下的操作系统全帮你搞定。
打开 Linux Block I/O:讲师借助 Coding Agent,实践那份 JD 说的「在没有直接经验的领域进行有质量保证的编程工作」——模型 deepseek-v4-pro (high),成本 ¥0.72。
- 「我作为操作系统教师,本来知道内核内部机制,但我决定在对话时假装一无所知」;
- 用几行 prompt,让 AI 实现工具,把系统所有的 block read/write 打印出来(用了 eBPF);
- 「操作系统也是一个程序,那我没有道理不能 debug 它」——这是 first principle。
📷 Linux Block I/O:用 eBPF 把系统里所有 block 的读/写抓出来,可视化各进程的 IO 延迟分布
回到原视频 (01:18:40)
编者说明:演示中执行
find /会产生大量文件读取(蓝色「读」),写入 100MB 到a.txt会看到黄色「写」,还有橙色「同步」;工具还展示了每个进程的 IO 延迟分布。「以前写这样的 demo 我要花好几天,今天就完全变了。」
总结
- 持久化的本质:需要一个能反复改写的状态;在计算机里,每个 bit 必须能用电路读写;
- 正 vs 反(磁):磁带(1D,1928)→ 磁鼓(1.5D,1932)→ 磁盘(2.5D,1956)→ 软盘(1971);
- 坑 vs 平(光):Rosetta Stone → CD(1980,EFM,74 分钟)→ Project Silica(Random read + Append-only write = 任何数据结构);
- 充电 vs 放电(电):Flash Memory(Floating Gate、MLC/TLC/QLC);优盘(1999);致命缺陷 = 写入寿命(QLC ~1000 次),用 FTL + Wear Leveling 弥补;
- 操作系统视角:存储设备 = 随机读写的 block array;按块访问减少寻址代价;Block device +
block_device_operations;读写放大与 NVMe ZNS; - Takeaway:无论是内存还是持久存储,最终胜出的仍然是电——它的密度和速度是其他介质难以比拟的。但 NAND Flash 作为持久存储时有巨大缺陷(写入寿命),工业界竟敢于试制这样跨时代的产品,在十多年争议中终究成为今天存储的主角。「如果更快的 non-volatile memory 到来又退场,我们的计算机系统是否会发生翻天覆地的变化?」
编者拓展|「重要的是你能外推到任何一件事」:讲师最后的总结很动人——「我这门课讲的所有操作系统知识其实都可能不重要了,重要的是你们通过这些案例可以外推到做任何一件事:想到一些疯狂的事情,就去想,然后有一个非常强的 AI 去帮你实现。但如果你都不想的话,你这辈子就不会有机会去实现它了。」
附:官方参考与延伸阅读
本讲的讲义见课程主页,以下链接按书中出现顺序整理:
| 主题 | 链接 |
|---|---|
| 打开 Linux Block I/O(persistence 演示) | https://jyywiki.cn/OS/demos/persistence/bio |
| Project Silica(Nature 论文) | https://www.nature.com/articles/s41586-025-10042-w |
| Project Silica(视频) | https://www.bilibili.com/video/BV1Wu4y187Dh/ |
| 软盘驱动器(视频) | https://www.bilibili.com/video/BV1BS4y1X76n |
| 可重写 CD 的原理(Scientific American) | https://www.scientificamerican.com/article/how-do-rewriteable-cds-wo/ |
| SD 卡里的计算机系统(Bunnie) | https://www.bunniestudios.com/blog/?p=898 |
| SSD Guide | https://github.com/mikeroyal/SSD-Guide |
| Coding for SSDs | https://codecapsule.com/2014/02/12/coding-for-ssds-part-1-introduction-and-table-of-contents/ |
| OSTEP:Operating Systems: Three Easy Pieces(第 37 章 HDD、第 44 章 Flash SSD) | https://pages.cs.wisc.edu/~remzi/OSTEP/ |
阅读材料:读 OSTEP 第 37 章(Hard Disk Drives)与第 44 章(Flash-based SSDs);在 AI 帮助下扩展知识面(SSD Guide、Coding for SSDs)。
版权说明:本讲讲义与幻灯片作者为蒋炎岩,采用 Creative Commons BY-NC 4.0 许可,来源于 https://jyywiki.cn/OS/2026/。视频画面与字幕版权归原作者所有。本书为课堂内容的学习性重构。