我们在过去经常看到一些计算机知识科普:机械硬盘磁头像可以动的录音机的读写头,盘片像扁平的多轨磁带,磁畴方向就是 0 和 1,读出来的就是干净的数字信号。理解起来简单、直观,但可惜这几乎完全是错的。
基础科普里常见的画法是这样的:
- 盘面被画成一格一格
- 每个格可以是 “磁化方向 A = 1”、“磁化方向 B = 0”
好像盘片就像内存条一样,一格一个 bit
为了好懂这种画法情有可原,但如果真的这么理解的话,就会错过整个现代磁记录技术的精髓。难得抽出时间水点博客,就让我们重新认识一下现在已经垂垂老矣的机械硬盘。
背景知识:操作系统眼中的硬盘(可以跳过不读)
对操作系统底层来说,硬盘的结构非常简单:一维数组。再业余一些来说,就是一组编号从 0 开始,一直到 N 的格子,从 0 到 N 的编号就是逻辑区块地址,也叫 LBA。
每个格子就是一个块,每个块可能有 512 字节或者现在更常见的 4096 字节容量空间,操作系统不能对每个块做精细到 bit 的寻址,如果你的硬盘块大小是 4096 字节的容量,那每次最少都要读取写入一整个块(4Kb)的数据,所以在文件系统格式化时才有了 4K 对齐这样提升效率的做法。
所以硬盘会被称之为“块设备”,而一维数组的特性决定了操作系统根本不知道自己把数据存在了物理上的什么地方,存储在物理上的什么地方完全是硬盘自己决定的,硬盘留给操作系统的结构就这么简单直观。
另外,很多人可能听过 柱面(Cylinder)/ 磁头(Head)/ 扇区(Sector)的 CHS 模型,这是非常早期的硬盘里的做法。这个模型确实能对应物理结构:“第 11 个柱面、第 4 个磁头、第 514 个扇区”,这样操作系统确实可以把数据放在想要的位置上。但这种结构非常非常古老,如果你的硬盘容量大于 8G,生产日期晚于 1995,就算硬盘支持 CHS 命令,实际上在硬盘主控里也早就把这些 CHS 翻译为 LBA 然后由硬盘自己决定怎么安置数据了。
所以说,硬盘要如何记录数据这件事对操作系统,哪怕是开发文件系统和操作系统的程序员来说已经完全是黑盒和魔法了。
固态硬盘自己的魔法是一些 FTL 映射表操作:磨损均衡、坏块替换一类的事情。
而对于机械硬盘来说,上面的魔法其实大差不差,而最大的神秘莫过于访存硬盘盘片的过程。
写入:调制、模拟载波
🤧注意!这些东西非常硬核,我找不到太多的资料,我在最开始的资料整理时大量使用了 ChatGPT,但我也对每个提到的点进行了查询考证,最终总能在一些教科书和论文以及厂商的白皮书中找到蛛丝马迹,可以放心阅读。
如果简单把 “磁化方向 A = 1”、“磁化方向 B = 0” 通过磁头硬写上去,读回来的信号会非常难以区分,而且几乎没有办法做时钟恢复(要知道磁场交变才会产生电流,连续 1 和连续 0 读头不输出有效信号)(可拓展阅读光盘的记录原理);
如果真的直接一串 0/1 原样写成磁化模式,会有至少三个大问题:
- 时钟恢复困难
- 如果连续写很多个 0 或 1,磁化就长时间不翻转
- 读头输出的波形就接近直流+微小噪声
接收端根本无法从中准确恢复每个 bit 应该在哪里
- 频谱特性差
- 信号中直流分量太多,不利于通道(前置放大器、读头)的频响
- 会带来很多防不胜防的干扰与失真
- 纠错冗余难以安排
- 如果只靠写两遍读两遍来对抗错误,将会像 RAID1 一样损失成倍的存储密度
- 需要有系统的纠错码 ECC 设计
如果改成控制翻转的位置和频率,就会有很多信号处理上的好处,比如更好的频谱特性和更可靠的时钟恢复,所以磁头的读写本质是模拟信号,这与通讯中的调制如出一辙。如果找个示波器以某种方式连接到磁头上应该可以观察到这样的现象:
- 当磁化翻转时,电压出现某种形状的波峰或波谷
- 相邻翻转之间的间隔、强度叠加在一起形成一条连续曲线
- 再加上噪声、失真、伺服误差等,最终产生一条抖抖晃晃的模拟波形,而不是干净纯粹的方波
所以在设计这个模拟信号的时候,这些问题必然需要考虑
- 什么时候翻转
- 翻转的频率区间
- 整体信号的结构
这些东西完全可以类比为数字通信技术:
源数据 → 纠错编码 → 通道编码/调制 → 转成模拟信号 → 发射到一个有噪声的通道里。
区别只是,这个通道不是空中电磁波,而是高速旋转的磁盘介质。
数据读取:最大似然解码
读头出来的电压信号很微弱,而且掺杂着各种噪声和失真,磁道间的干扰当然存在,磁头的定位也不一定非常准。总之,这是机械硬盘最精彩的部分!
模拟前端
硬盘控制芯片上的模拟前端会先做几件事:
- Preamp(前置放大):把信号放大到合适范围
- AGC(自动增益控制):动态调整放大倍数,避免信号太弱或饱和
- 模拟滤波:滤掉频谱中明显无用的部分,防止别的噪声占满通道
这一部分和射频接收机里的前置放大 + 模拟滤波几乎一样,只不过频率更低、目标信号形式不同而已。
此时,该信号将送入 ADC 进行采样为数字信号,对于采样速度的话可以简单估计:典型 7200 转 HDD 外圈顺序速度大概可以达到 150–200 MB/s,200 MB/s ≈ 1.6 Gbit/s(用户 bit,不含冗余/ECC/编码开销);算上编码、冗余、同步、ECC 一类的额外数据,真实的磁记录符号率可能要达到 1.6 Gbit/s 的两三倍;再考虑奈奎斯特采样定理,该 ADC 可能需要应对几百 MHz 的采样率,如果是高密度盘的话,要求只会更高。虽然采样率可能会远超消费级示波器的范围,但还好这套流程下来对分辨率的要求不高。
现在我们进入了数字时代,后面的事情交由基带(通道处理器)处理:
数字通道
均衡(Equalization)
通道的频响并不是理想的,码间干扰(ISI)很严重:
- 某个位的信号,会“拖尾”影响到前后若干个采样点
- 这样接收端看到的不是一个个孤立的脉冲,而是一条“你中有我、我中有你”的混合波形
数字均衡器(滤波器)会尝试把这个复杂的通道响应整形
让它变成一个已知形式的部分响应通道(比如 PR4、EPR4 等)
便于后面用统一模型去处理。
PRML(Partial-Response Maximum-Likelihood)
- “Partial-Response” 是对通道做建模:承认它有码间干扰,但这个干扰是有规律的
- “Maximum-Likelihood” 是在这个模型上,找最可能的比特序列
你可以这样理解:
我知道这个通道会让一个 bit 影响到周围 2~3 个采样点;
现在我看到了一串采样值,
我要在所有可能的 bit 序列里,挑出那个“通过这个通道模型后,最有可能产生这串采样值”的序列。
Viterbi 序列检测
实际上做最大似然序列估计时,常用的是 Viterbi 算法:
- 把“可能的 bit 序列”当成一个状态机路径
- 每条路径都有一个“代价”(偏离实际采样的程度)
- 从头到尾动态规划,最后选出“总代价最小”的路径(也就是最可能的 bit 序列)
用更形象一点的比喻:
想象你在听一段被严重回声、噪声污染过的 Morse 电码录音
每个“滴”都拖尾、重叠,你没办法逐个音节判断
你只能拿整段节奏一起看,结合上下文和物理规律
猜这应该是那句电文里最可能的一种符号序列
HDD 读通道做的,就是这种 Gbit/s 版的猜电码,只不过它有一个非常精确的数学模型和算法支持。
ECC
即便有了 PRML + Viterbi,仍然会有剩余误差。
这就是之前写入时做的纠错码(ECC)登场的地方:
- 对读出的 bit 流做校验
- 检测并纠正一定数量的 bit 错误
- 如果错误太多,超过纠错能力,就报错(UNC 等)
最终,经过这么多道处理,你才能得到那一小块 4K、512B 的数据块。
从这一步开始,硬盘才会把这个数据块交给文件系统或调用者,回到我们熟悉的“文件”和“字节流”的世界里。
结语
虽然固态硬盘有 MLC TLC 和 QLC 一说,也确实在一个单元内存储了模拟量,但概念完全不一样。固态硬盘是多电平的数字存储方式,而机械硬盘则完全是以模拟方式存储的。
机械硬盘也会消磁,盘片上的物理存储位置也未必是从写入时就确信要写在这里的。它会在空闲时做自己的整理,这点和固态硬盘的磨损均衡一样对用户不可见,但用户有时候也能听到它自己在工作而看不到硬盘灯的闪烁。
也许再过几年,桌面机里用机械盘装游戏、装系统的场景会越来越少,它们会退回到 NAS、冷数据仓库、机房一角的磁阵里,最后慢慢从普通用户的视野里消失。
但在那之前,至少我们可以不再把它简化成“一个线圈写 0 和 1”那么粗糙的东西,也不要觉得这是磁性版的打孔纸带。
机械硬盘,是人类工程技术里
把机械、材料、模拟电路、数字信号处理和编码理论
塞进一个 3.5 寸铁盒子里的复杂而优雅的一小支分支。