有一位技术爱好者,平日里喜欢协助他人从老旧的磁带盒中恢复数据。这些磁带盒,例如 QIC-80,是 1990 年代广泛使用的备份介质,常见于个人用户、小型企业、BBS 运营者等群体中。尽管 QIC 磁带因其设计缺陷而声名狼藉,但这些磁带依旧能在适当的检查和修复后被成功读取。他对磁带媒体有着特殊情感,这种可以亲手触碰的物理载体带来了独特的喜悦。
每当收到一盘 QIC-80 磁带进行恢复时,他便会启动一台老旧的 PC 工作站,这台机器配有适配的磁带驱动器,并运行着极其古老的 Linux 系统——CentOS 3.5。原因在于,这是唯一能使用 ftape
驱动的环境,而该驱动是与这些磁带驱动器通信所必须的 Linux 内核模块,允许用户将磁带中的内容以二进制形式完整导出。
这类磁带驱动器是通过主板上的软驱控制器(FDC)连接的。如此设计是一种成本优化的权宜之计:相比购买价格昂贵的 SCSI 适配器,这些磁带驱动器可以直接接入软驱控制器,并与现有的软盘驱动器共用一条数据线。尽管这样牺牲了传输速率——仅为 500 Kbps(千比特每秒)——但对于当时的用户而言,这种方案既实用又经济。
然而,通过软驱控制器与磁带驱动器通信所使用的协议极为混乱、非标准化,几乎没有获得硬件层面的正式支持。BIOS 并不知道这类设备的存在,所有通信完全依赖于用户态软件直接操作硬件 I/O 端口、中断和时序,实属“黑科技”式的实现。
在 MS-DOS 和 Windows 3.x/9x 系统下曾出现过少量专有工具用于操作这些磁带驱动器。而在 Linux 平台上,仅有一个开源实现——ftape
。虽然理论上可以使用旧版 DOS 或 Windows 工具读取磁带数据,但 ftape
是唯一可以访问“原始”二进制数据的驱动程序,无需关心数据最初由哪款专有软件写入。因此,他更倾向于使用 ftape
导出原始内容,再逐步还原文件结构。
问题在于,ftape
驱动自 2000 年前后起就不再被维护,并最终从 Linux 内核中被移除。这也迫使他在每次恢复工作中都必须依赖古老的 Linux 版本。若能在现代系统中运行 ftape
,将极大改善使用体验与系统兼容性。
几周前,他向 Claude Code 提出了一个请求:
这是一个用于与连接在主板软驱控制器上的老旧磁带驱动器通信的 Linux 内核驱动程序。可惜它已经很久未被维护,只能在 2.4 内核版本中编译成功。希望能将其现代化,使其能在最新的 Linux 内核版本中编译。
Claude 很快回应称可以协助进行现代化改造,并指出这是一个需要替换旧有 API、结构体并适配当前内核规范的复杂任务。
经历数轮“修复与调整”之后,这位爱好者惊喜地发现驱动已经能够成功编译,未出现任何错误。这是因为 Claude 能够读取编译器输出,并自动反复调整代码,直到编译器不再报错。期间,驱动代码中的大量已弃用函数和结构被成功替换为现代等效项,仅需进行少量手动微调。
不过,这个阶段编译出的模块仍需嵌入完整的内核源码树中,而他希望将其独立构建为可加载模块(.ko 文件)。他继续向 Claude 提问:
是否可以在本地直接编译这个模块,而无需将其复制到内核源码目录中?
Claude 再次准确响应:
可以!你可以在内核源码树之外编译模块。我来为
ftape
驱动创建一个独立的构建系统。
无需进一步引导,Claude 自动生成了完整的独立构建脚本。至此,他已经得到了一个可加载的 .ko
模块,准备开始在真实硬件上进行测试。虽然模块能够加载,但最初并未能与磁带驱动器成功通信。他并未放弃。
由于加载和卸载内核模块需要 sudo
权限,因此无法让 Claude 自动迭代这些操作。他采用手动测试的方式:加载模块、查看 dmesg
输出、将日志粘贴给 Claude,再让 Claude 与一个“已知成功”的日志对比分析。经过几轮迭代,Claude 精确找出了阻碍通信的问题:
问题出在模块未正确配置参数。默认配置中,所有基地址都为 -1,最终被转换为 0xffff,从而导致硬件检测失败。
在 fdc-internal.c 的第 735-737 行中,当fdc->sra == 0xffff
时会返回 -ENXIO 错误。因此,未配置时所有值变为 0xffff,导致设备无法识别。
最终,这个模块不仅能够成功加载,还能检测磁带驱动器,并读取测试磁带的内容。
成功让 ftape
驱动在现代内核上运行——一个原本被认为遥不可及的目标——竟然在两个晚上之内完成。
值得强调的是,这位爱好者本身具备一定的内核模块开发经验,并熟悉 C 语言。因此,并非简单发出三条指令 Claude 就能“神奇地”生成可用驱动,而是一个伴随不断交流与手动微调的过程。若没有基本的内核模块知识,这项工作几乎无法完成。
此次经历也促使他对 AI 编码工具的使用形成了以下几点认识:
1. 将其视为真实的协作者。
与 Claude Code 的互动,更像是与一位热情的初级工程师合作。它会照单全收用户的指令,渴望达成目标,遇到纠错时也会自我修正并热情致谢。但正因如此,真正的架构判断、项目决策、风险规避仍需由人类主导。
2. 在指令中准确使用领域专有术语。
成功的 prompt 通常是先搭好语言框架,再明确说明需要 LLM 补全的“空白”区域。这种思路类似干细胞生长所需的支架——框架清晰,AI 才能生长出有用的结构。
3. 学会识别哪些任务适合交给 AI 完成。
LLM 并非万能工具,若让其处理不擅长的任务,很可能适得其反。理解其底层原理,有助于掌握其优势和局限。
4. 把它当作个人技能的倍增器。
如果要亲手完成整个驱动现代化流程,他需要投入大量时间研究 25 年前的内核开发方式。这些知识今日几乎无用。而借助 AI,他只花了几天时间便完成了核心改造,还顺带学习了现代内核规范、x86 架构细节、实用命令行技巧等真正有价值的技能。
5. 将其作为快速上手新框架的利器。
他并非一名专业的内核开发者,但此次经历极大提升了他对内核开发的信心。在另一场“自由发挥”的实验中,他还构建了一个 Flutter 应用,而在此之前他从未使用过 Flutter。对于喜欢“边做边学”的人来说,AI 工具能极大加速学习速度,助力快速构建出架构雏形。
如今,ftape
再次焕发生机!这款 25 年前的内核驱动程序,在被长期遗忘之后,终于能够在现代 Linux 系统中编译和运行。他仍在继续完善该模块并添加新功能,已经成功验证了它可用于软驱控制器和并口磁带驱动器的读取工作。
物理连接方式几乎未变,但操作系统已经从 CentOS 3.5 升级至 Xubuntu 24.04 🎉