DavidClawson/gw1n2-apicula

GitHub: DavidClawson/gw1n2-apicula

为 Project Apicula 补充 Gowin GW1N-2 FPGA 比特流支持的开源逆向工程项目,通过差分模糊测试方法构建芯片数据库。

Stars: 0 | Forks: 0

## 为什么 GW1N-2 具体来说是道墙 Apicula 0.32(PyPI 上的最新版本)内置了恰好这 10 款设备的 chipdb: ``` GW1N-1, GW1N-4, GW1N-9, GW1N-9C, GW1NS-4, GW1NZ-1, GW2A-18, GW2A-18C, GW5A-25A, GW5AST-138C ``` 没有 GW1N-2。IDCODE 门控在 `apycula/bslib.py` 中是一个字面字节匹配列表(`read_bitstream`,约第 96–127 行);GW1N-2 流的 device-ID 命令 `06 00 00 00 01 20 68 1b`(= IDCODE `0x0120681B`)无法匹配任何内容,并抛出 `ValueError("Unsupported device")`。该检查在 *嵌入在 bitstream 中* 的 IDCODE 上运行,位于任何 `-d DEVICE` 标志的数据库加载 **之前** —— 因此没有任何标志可以绕过它。真正的修复方法是提供一个真实的 GW1N-2 chipdb,而不是调整配置。 **关系最近的现有同族设备:** `GW1NZ-1`,IDCODE `0x0100681B` —— 共享 `…681B` 家族尾缀,仅有一个字节不同。它是分支开发的天然模板。 ## 方法,用一段话概括 这是 **差分模糊测试 (differential fuzzing)**,不是随机猜测。你使用 Gowin 自己的(免费、闭源的)EDA 工具作为编译 *预言机 (oracle)*:生成一个只设置一个底层架构特性的最小设计(一个 LUT 真值表、一条布线、一个 IO 缓冲器),编译它;再生成一个仅在该特性上有所不同的几乎相同的设计,同样编译它,然后 **对比两个 bitstream** —— 翻转的位就是控制该特性的位。在整个 tile 网格上系统地重复此操作,构建位 ↔ 特性映射(即“chipdb”)。Apicula *还会* 解析 Gowin 内置的内部架构/时序文件(`.fse` / `.dat` / `.tm`),这些文件已经编码了大部分结构 —— 因此这部分是厂商文件逆向工程,部分是差分模糊测试以确认位位置。自底向上的顺序:网格/IO → LUT/DFF → 布线 → BRAM → PLL。 ## 状态 - [x] 确认了阻碍因素(Apicula 设备数据库中缺少 GW1N-2) - [x] 提取并验证了真实环境的验证 bitstream (`reference/`,sha256 `5a0e7338…`) - [ ] 搭建环境(Gowin EDA + Apicula 克隆 + 参考构建)— `docs/01` - [ ] 复现 GW1NZ-1 参考构建作为模板 — `docs/01` - [ ] 映射 GW1N-2 网格/IO — `docs/02` - [ ] 映射 GW1N-2 逻辑原语 (LUT/DFF) — `docs/02` - [ ] 映射 GW1N-2 布线 — `docs/02` - [ ] 映射 GW1N-2 BRAM/PLL — `docs/02` - [ ] `gowin_unpack` 在验证 bitstream 上成功运行 - [ ] (延伸目标)nextpnr-himbaechel 设备数据 → 编写自定义 GW1N-2 bitstream ## 今天你能做什么 请对这道门槛保持清醒认识:**这是进行中的研究,还不是一个可用的工具。** 标题中提到的 `gowin_unpack -d GW2N-2 …` 工作流在任何人的设备上都无法运行,除非 GW1N-2 的 chipdb 存在并被合并到 Apicula 中(即上面未勾选的选项)。在此之前,以下是针对不同受众的坦诚说明: | 你想要… | 今日状态 | |---|---| | **阅读逆向工程故事**(Gowin bitstream 如何工作,如何模糊测试 chipdb) | ✅ 现在即可 — 从 `docs/00` 开始 | | **复现侦察过程**(header/IDCODE 解析,`bin2fs`,格式检查) | ✅ 现在即可运行(Python;不需要 Gowin EDA) | | **运行模糊测试流程**(自己构建 chipdb) | ⚠️ 需要 Gowin EDA + Linux 机器 — 见 `docs/01`,`docs/05` | | **解包真实的 GW1N-2 bitstream** | ⛔ 受阻于 chipdb(即上方的里程碑工作) | | **修改 FPGA 行为并重新打包**(实验性设计) | ⛔ 需要解包 **并且** 需要一个可用的重新打包往返流程(`tools/roundtrip/`,早期阶段) | **值得关注的两个解锁时刻:** (1) chipdb 合并到 Apicula 上游,这将使其从“仅供阅读”变为“任何人都可以解包 GW1N-2 bitstream”;(2) 可用的解包→修改→重新打包的往返流程,这将使其变为“实验者可以修改 GW1N-2 bitstream” —— 届时这将成为一个用于自定义 GW1N-2 工作的实验性姊妹仓库(见 [`docs/09`](docs/09-openscope-context.md))。 ## 对其他 GW1N 设备的参考价值 由此产生的 *bitstream* 是设备锁定的 —— Gowin bitstream 携带自身的 IDCODE 以及特定于裸片的网格/帧布局,因此 GW1N-2 镜像无法加载到 GW1N-1、-4 或 -9 上(IDCODE 门控会拒绝它,并且即使强制加载,架构坐标也无法对齐)。不存在“一次编写,全系列通用”的情况。 *能够* 传递的是知识和工具。GW1N 系列(即“LittleBee”一代)共享一种架构 —— 相同的 LUT4/DFF 原语、IO 块结构和路由多路复用器风格 —— 而 Apicula 正是基于此构建的,它提取了共享的每个裸片的数据,而不是将每个设备视为孤立的存在。(此处的 GW1N-2 通过 GW1N-1P5C 裸片数据进行解包:Gowin 自己的文件已经将它们视为相关的裸片。)因此,每个 tile 的位 ↔ 特性映射和模糊测试脚本(`tools/m*_*.py`)是一个现成的 **该方法参考实现**,任何希望将另一个尚不支持的 Gowin 设备引入 Apicula 的人都可以重用它 —— 而不仅仅适用于 GW1N-2。 ## 诚实的范围 为了明确这是什么以及不是什么:这里的实际目标 **不是** 从头开始重新设计 scope 的 FPGA。其目标是更窄、更易于实现的 —— 寻找通过 *修改现有库存 bitstream* 来增加功能的方法,理想情况下无需完全逆向工程原始设计。这项工作本质上是与特定设备和 scope 的上下文绑定的。 因此,对于任何没有 2C53T 硬件和该上下文的人来说,这个仓库最好被当作一个 **研究和参考资源** 来阅读 —— 一个有文档记录的方法、一个 chipdb 以及一套模糊测试工具 —— 而不是一个你可以直接指向自己的开发板并立即使用的工具。这是有意为之的,上面提到的跨家族说明正是能够广泛传播的那部分。 ## 文档 - `docs/00-background.md` — 设备、IDCODE 墙以及 bitstream 模糊测试的工作原理 - `docs/01-environment-setup.md` — Gowin EDA、Apicula 克隆、复现已知良好的设备构建 - `docs/02-methodology.md` — 自底向上的模糊测试计划,使用 GW1NZ-1 作为模板 - `docs/03-workplan.md` — 里程碑清单以及我们将如何确认每一步是否成功 - `docs/04-contributing.md` — 如何按照维护者的期望将 GW1N-2 支持合并到上游 - `docs/05-needs-david.md` — 只有真人才能解决的阻碍(Gowin EDA 安装,Linux 环境) - `docs/09-openscope-context.md` — 起源故事 + 与 OpenScope 固件项目的关系 - `setup.sh` — 用于 Linux 机器的可运行环境引导程序(已针对真实仓库验证) ## 许可证 MIT(见 [`LICENSE`](LICENSE)),与 Apicula 的许可证相匹配,以便在此处生成的任何 chipdb 都能干净利落地 **贡献给 Apicula 上游**。本仓库是工作区 + 工具 + 笔记,而不是一个分支;chipdb 的工作将在 Apicula 仓库的克隆中完成(见 `docs/01`)。
标签:EDA, FPGA, 云资产清单, 差分模糊测试, 芯片数据库, 逆向工具, 逆向工程, 高云半导体