第39期 | 硬盘不认字,内核怎么跟它说话?

操作系统 · · 九羲科技

一、硬盘不认字,只能抠端口

1991 年最手工的一块代码,是硬盘驱动¹

1991 年 9 月,Linux 0.01 里最"手工"的一块代码,是 kernel/hd.c。开头注释先打预防针:"relatively straigthforward (not obvious maybe, but interrupts never are)"——straightforward 拼错了,可见写得多赶。

硬盘不认字。内核跟它说话,全靠十六个端口:0x1f0 到 0x1f7,一个字节一个字节地抠。0x1f0 是数据口,0x1f7 既是状态口又是命令口。想读一个扇区?先把柱面、磁头、扇区号填进各个口,最后往 0x1f7 扔一个 0x20(WIN_READ),然后等中断。512 个字节回来,分 256 次搬,每次一个字——port_read 宏里那句 rep;insw,干的就是这个。

Linux 0.01 kernel/hd.c 开头的注释(含拼错的 straigthforward)、port_read/port_write 宏,以及 hdreg.h 里那句"Not beatiful, but easier"。来源:kernel.org historic 源码包,一手核对。

1991 年的硬盘有脾气。几何参数直接焊死在 hdreg.h 里,注释写得理直气壮:"currently supports only 1 hd, put type here","Not beatiful, but easier"——beautiful 也拼错了。更妙的是 config.h:#define LINUS_HD,旁边注释掉一行 #define LASU_HD。编译时二选一:这是 Linus 自己的硬盘,还是他朋友的硬盘。0.01 的硬盘驱动,字面意义上只认他自己那块盘。

土办法里藏着真功夫。请求队列按(盘号,柱面,磁头,扇区)排序,磁头少跑冤枉路——电梯算法,0.01 就有了,注释还得意一句:"doesn't need to disable interrupts due to clever programming"。出错了呢?MAX_ERRORS 设成 5,五次读不出来就 reset_controller:往命令口扔个 4 再扔个 0,整个控制器重启。打不过,就重启。

还有一处倔强。sys_setup() 开机先读 0 柱面 1 扇区,偏移 0x1BE 处必须是分区表,510、511 字节必须是 0x55、0xAA,对不上直接 panic。分区表不对,宁可死,不开机。

庖丁"依乎天理,批大郤,导大窾"²——顺着牛天然的纹理下刀。hd.c 顺的,是控制器的天理:哪个口先写、哪个状态位算忙,错一步就死机。道和技,在这里是同一件事。

这是发展性研究,不是原理突破。IDE 那套"任务文件"寄存器接口是现成标准,0.01 没发明任何新原理——赢在把端口时序一根一根抠对。杨振宁 1981 年信里说的"先实际后原理"³,就是这个意思。

二、AI 的硬盘,装的不是文件:如果 AI 的 OS 先出现

如果 AI 的操作系统先出现,它大概不会有 hd.c 这样的文件。不是不需要存东西,是要存的东西变了:权重、KV cache、向量索引、checkpoint——没有一样是"第几个扇区"能描述的。

0.01 的电梯按柱面给请求排队,省的是磁头的机械移动。AI 时代的"电梯"排的是另一维:显存。PagedAttention 把 OS 的分页思想搬进 KV cache⁴:每个请求的缓存切成小块,按需分配,把原来 60–80% 的显存浪费压到接近于零。当年省的是寻道时间,今天省的是显存——排队的维度变了,"排队"这件事没变。

范式之眼在这里收紧:块设备="线性扇区数组",是为旋转磁盘设计的旧抽象。SSD 让随机读≈顺序读,柱面磁头成了泡影;GPU 要的更不是扇区,是"这批张量放哪、多久能拿回来"的批量语义。AI OS 的存储层不会再问"第几个扇区",它问的是:这段记忆热不热,值不值得留在显存里。

可能性:存储从"地方"变成"记忆"——按热度分层,按语义寻址。落地还差几步:统一的"记忆分级"语义缺标准,checkpoint 缺跨框架格式。谁来做?推理引擎先长出来——vLLM 已经是应用层的 hd.c 了,再往下沉。三到五年,能看见形状。

三、今晚,看一眼你机器的硬盘:三件事,亲手摸一遍 1991

第一,看端口。下载 0.01 源码包(72KB),翻 include/linux/hdreg.h:从 HD_DATA 0x1f0 到 HD_COMMAND 0x1f7,找那句 "Not beatiful, but easier";再看 kernel/hd.c 开头,找拼错的 "straigthforward"。二十一岁的人写代码,错别字都理直气壮。

第二,看电梯。grep -n "IN_ORDER" kernel/hd.c——四行宏,(盘号,柱面,磁头,扇区)逐级比,1991 年的请求调度长这样。

第三,对比今昔。在手边任何一台 Linux 机器上跑:lsblk -d -o NAME,SIZE,ROTA,看你的盘转还是不转;cat /sys/block/sda/queue/hw_sector_size——大概率还是 512,三十五年前的扇区大小,化石一样活到了今天;dmesg | grep -iE "nvme|ahci",看今天的内核怎么认盘,不再是焊死的两块。

把这套思路搬到今天的行业实践里:本地跑大模型的机器上,NVMe 驱动是 hd.c 的曾曾孙——从抠端口到几万深度的并行队列,路还长;边缘计算盒上的 eMMC,驱动薄、脾气小,0.01 式"焊死参数"反而是优点,简单可靠;视频 AI 平台每路视频的录像落盘,就是当年的 write_intr,只是"五次失败就放弃"在今天不可接受,得换成重试加校验;企业私有智能中心做私有化部署,第一步还是 1991 年那一步:先认盘,再谈别的。

觉 然 小 注

「一切有为法,如梦幻泡影,如露亦如电,应作如是观。」柱面磁头扇区,1991 年是天理,SSD 一来全成泡影。别把任何一版"天理"当永恒——顺着变,本身就是天理。

引 用 与 出 处

  1. [1] Linus Torvalds. linux-0.01.tar.gz(源码包;kernel/hd.c、include/linux/hdreg.h、include/linux/config.h 为一手核对). kernel.org Historic 存档, 1991. https://mirrors.edge.kernel.org/pub/linux/kernel/Historic/linux-0.01.tar.gz
  2. [2] 《庄子·养生主》(郭象注本通行本;"依乎天理,批大郤,导大窾"为思想化用). 公有领域.
  3. [3] 杨振宁. 1981 年致信国家领导人(1982-03-05《光明日报》发表;"发展性研究""先实际后原理"为思想化用).
  4. [4] Kwon, W. et al. Efficient Memory Management for Large Language Model Serving with PagedAttention. SOSP, 2023. https://arxiv.org/abs/2309.06180

· · ·

← 返回资讯中心