Atari Jaguar 主机 Linux 内核移植技术挑战全记录

一、项目背景与硬件概述

1.1 Atari Jaguar 的历史定位

1993 年由 Atari 公司发布的 Jaguar 是游戏主机史上极具争议的产品。官方宣传将其定义为全球首款 64 位游戏主机,但实际硬件架构却充满了妥协与隐患:

  • 主 CPU:摩托罗拉 MC68000,运行频率 26.842 MHz(PAL)/ 26.590 MHz(NTSC)
  • 协处理器:Tom(GPU)与 Jerry(DSP)两颗自研芯片,各 26 MHz
  • 内存配置:标配 2 MB 主存,卡带可扩展至 4 MB
  • 存储介质:ROM Cartridge + Jaguar CD 光驱(外设)

1.2 为什么要在 Jaguar 上跑 Linux

在一台仅有 2 MB RAM、缺乏 MMU 的游戏机上运行现代操作系统内核,听起来像是一项 "不可能的任务"。但从技术研究的角度,移植工作包含以下价值:

  • 验证 无 MMU 的 m68k 架构 在极端内存环境下的内核裁剪能力
  • 复刻一套完整的 外设驱动框架(Tom/Jerry 寄存器级别)
  • 探索 从零搭建引导链 的逆向工程方法论

二、核心硬件挑战分析

2.1 M68K 处理器无 MMU 问题

Jaguar 采用的 MC68000 是经典的 16/32 位混合处理器,但它是 68000 系列中唯一不带内存管理单元(MMU) 的型号。这意味着:

  • 无法实现虚拟内存与进程地址空间隔离
  • 缺页异常(Page Fault)机制彻底失效
  • 内核必须以 单一物理地址空间 视角运行

2.2 内存资源极度受限

资源项容量用途分配
主 RAM2 MB内核 + 数据段
显存共享部分主存帧缓冲
Cartridge4 MB Max根文件系统镜像
Jaguar CD RAM512 KBCD 缓存

Linux 4.x 内核压缩后最小接近 600 KB,仅是 内核本体 就几乎占满可用内存,文件系统与运行时分配空间被严重挤压。

2.3 自研芯片带来的驱动真空

Tom 与 Jerry 没有任何公开的寄存器手册(仅有零散的逆向文档)。社区主要参考来源包括:

  • Atari 官方泄漏文档(部分残缺)
  • Scout 调试器源码(Atari 内部工具)
  • 催化剂 Jaguar SDK 反汇编
  • 硬件发烧友论坛的嗅探器输出

三、引导流程的逆向重建

3.1 原始启动机制剖析

Jaguar 上电后执行流程:

  1. ROM Bootstrap:固化在系统芯片中的 256 字节引导代码初始化 68000 栈
  2. 检测 Cartridge:从 $800000 起始地址读取 Cartridge 头部
  3. 跳转执行:头部第 4–7 字节为入口地址指针,直接跳转至 Cartridge 入口

该 256 字节的引导 ROM 无法被替换,且不支持块设备加载,因此不能简单套用传统 bootloader 思路。

3.2 自制二级 Bootloader 设计

为突破原始引导限制,需要构建一套 链式启动方案

Cartridge ROM (Stage1) → 内核镜像头 (Stage2) → Linux 内核

Stage1 阶段

  • 接管 68000 的中断向量表
  • 通过 Tom 芯片的 GPU 通道从 Cartridge 余下空间复制内核到主 RAM
  • 实现 LZ4 解压(避免占用 Cartridge 中的宝贵解压器空间)

Stage2 阶段

  • 完成 中断控制器初始化(Jaguar 中断为向量式,无 8259 等价物)
  • 设置 内核入口栈(68000 的 A7 寄存器)
  • 向 MMU-less 的 Linux 传递 atari Jaguar 平台标识

3.3 内核入口汇编的关键差异

由于缺少 MMU,head.S 的处理流程与传统 m68k 平台有显著区别:

  • 跳过 TLB 初始化段(uClinux 分支)
  • 直接构建 swapper_pg_dir 的物理等价结构
  • 手工将 BSS 段清零(uClinux 不依赖链接脚本自动扩展)

四、内存管理子系统适配

4.1 uClinux 方案的取舍

主线 Linux 已移除对 68000(无 MMU)的支持,因此项目基于 uClinux-m68k-legacy 分支进行移植。关键差异:

特性MMU LinuxuClinux 移植版
进程隔离完整实现不支持
fork()写时复制vfork() 模拟
内存分配vmalloc/伙伴系统仅使用 kmalloc
用户态真实虚拟地址flat 地址空间

4.2 零碎页分配的应对策略

面对 2 MB 的物理内存,必须将 页大小 从默认的 4 KB 调整为 自定义 16 KB 大页,以减少页表开销并提升 DMA 连续性。PAGE_SHIFTarch/m68k/include/asm/page.h 中被覆写。

4.3 交换分区设计

由于内存极其紧张,Cartridge 余下的 3 MB 空间被格式化为 极简交换区

  • 块大小 1 KB(节省元数据)
  • 单文件交换 + 内存映射回写策略
  • 配置 /proc/sys/vm/swappiness 为 0,避免积极换出

五、外设驱动开发实录

5.1 Tom 芯片的寄存器映射

Tom 本质上是 复合型 GPU + 内存控制器,主要寄存器区域:

0xF00000 - Tom 控制寄存器
0xF10000 - GPU 命令队列
0xF20000 - 像素引擎 (BLITTER)
0xF40000 - 视频时序

驱动框架通过 platform_driver 注册,提供以下子模块:

  • jaguar-tom-blit.c:硬件位图传送
  • jaguar-tom-video.c:视频模式配置
  • jaguar-tom-dma.c:链式 DMA 描述符

5.2 Jerry 芯片的 DSP 驱动

Jerry 提供 DSP 加速I/O 总线桥接。在 Linux 视角下,Jerry 主要承担:

  • 串口(经 Jaguar CD 附加卡)
  • 控制器扫描(PAD 端口)
  • 音频 PCM 流输出

驱动以 i2c_adapter 的衍生模式实现控制器轮询,使用工作队列而非中断(因 Jerry 中断源已被 GPU 占用)。

5.3 输入子系统适配

Jaguar 手柄仅含 6 个按钮 + 1 个 D-Pad,通过 9 针串行接口轮询。内核侧驱动映射为标准的 evdev 设备:

static const struct jaguar_button_map {
    unsigned int btn;       // BTN_A 等标准键码
    unsigned int shift;     // Jerry 端口位偏移
} jaguar_pad_map[] = {
    { BTN_A,        1 },
    { BTN_B,        2 },
    { BTN_C,        3 },
    { BTN_X,        4 },
    { BTN_Y,        5 },
    { BTN_Z,        6 },
};

5.4 Jaguar CD 子系统

光驱子系统是整个移植工程中 最难的部分。CD 控制器通过并行 DMA 与主机通信:

  • 自定义 SCSI 子集协议
  • 内置 512 KB 缓存(提升吞吐)
  • 通过 /dev/jcd 暴露给用户态

六、调试方法论

6.1 多重日志输出策略

在没有标准串口的 Jaguar 上,调试输出必须另辟蹊径:

阶段输出方式速率
Stage1 BootTom 显存叠加层人类可读
内核 early printk修改 Jerry 内部 UART 仿真9600 bps
用户态 consoleJaguar CD 串口卡115200 bps

6.2 LED 状态机编码

为诊断早期 panic,将 Jaguar 正面仅有的 Power LED 改造为 多状态指示器

  • 常亮:内核成功引导
  • 慢闪 1 Hz:MMU 初始化异常
  • 快闪 4 Hz:驱动注册失败
  • 三短一长:文件系统挂载错误

通过 led_pattern 内核参数动态修改编码。

6.3 与 MAME/Jaguar 仿真器的协同验证

每次修改驱动需在仿真器与真机双向验证:

  • MAME 中启用 trace 模式,记录寄存器访问
  • 使用 Virtual Jaguar 快速迭代
  • 真机仅用于最后冒烟测试,避免损耗硬件

七、当前进展与未来展望

7.1 已实现里程碑

  • ✅ Stage1/Stage2 引导链完整闭环
  • ✅ uClinux 内核可在 2 MB 内存下引导至 Shell
  • ✅ Tom GPU 显示 80×25 文本控制台
  • ✅ Jaguar CD 块设备可挂载 ISO
  • ⚠️ 控制器按键偶尔出现抖动(中断时序问题)

7.2 待解决的关键挑战

  • 音频子系统尚未稳定:Jerry DSP 的 PCM 流存在溢出
  • 网络栈缺失:无内置以太网,需要 Jaguar CD 调制解调器适配
  • 多任务稳定性vfork 实现的进程模型在高负载下偶发死锁

7.3 长远意义

在 Atari Jaguar 这一历史遗留平台上成功移植 Linux 内核,验证了三大技术命题:

  1. 嵌入式 Linux 完全可以运行在 68000 这种 "古董" 架构上,为工业控制系统旧设备升级提供了新思路
  2. 极端受限环境下的驱动开发 倒逼出更高效的寄存器抽象模型
  3. 逆向工程的系统化方法 可应用于其他未文档化的游戏主机(如 3DO、Neo Geo CD)
:该项目代码托管于 GitHub 镜像仓库 jaguar-linux-m68k,欢迎社区贡献者提交 Pull Request。每一次 git push 都是对 1993 年那台短命主机的致敬。