1. 比特流基础:FPGA架构概述、比特流是什么、比特流在FPGA启动中的作用
做逆向工程这么多年,我接触过不少硬件。但说实话,FPGA 这玩意儿,一开始真让我头疼。它不像 CPU 那样有固定的指令集,也不像 ASIC 那样功能焊死在芯片里。你拿到的是一块“白板”,想让它干什么,得你自己“画”上去。而这个“画”的过程,最终产物就是比特流。
今天这一章,咱们先把地基打牢。搞懂 FPGA 到底是个什么结构,比特流又是个什么鬼,以及它怎么让 FPGA 活起来的。这些搞不明白,后面逆向工具链根本无从谈起。
1.1 FPGA 架构:一张能“编程”的网
FPGA 的全称是现场可编程门阵列。名字很长,但核心就三个字:可编程。你想想看,一块芯片出厂后,你还能改变它的内部电路连接,这本身就是件很酷的事。
它的内部结构,说白了就是三大块:
- 可编程逻辑单元(Logic Block):这是 FPGA 的“肌肉”。每个逻辑单元通常包含一个查找表(LUT)和一个触发器(Flip-Flop)。LUT 负责实现组合逻辑,触发器负责时序逻辑。我习惯把 LUT 看成一张小真值表,你输入什么,它输出什么,全由你配置。
- 可编程互连资源(Interconnect):这是 FPGA 的“神经”。逻辑单元之间、逻辑单元与 IO 之间,全靠这些纵横交错的金属线和可编程开关来连接。逆向分析时,最难啃的往往就是这部分——你得从比特流里还原出这些开关的状态。
- 可编程输入输出单元(IO Block):这是 FPGA 的“手脚”。负责芯片与外界通信,支持各种电平标准,比如 LVCMOS、LVDS 等。我在一个项目中遇到过,因为 IO 配置错误,导致信号反射严重,整个系统跑起来像抽风一样。嗯,从那以后,我每次都会仔细检查 IO 的比特流配置。
这三者组合在一起,就构成了一张巨大的、可配置的“网”。你通过比特流,告诉这张网里的每个节点和每条连线该怎么工作。
核心要点: FPGA 不是“执行”程序,而是“变成”电路。比特流就是描述这个电路如何连接的“施工图纸”。
1.2 比特流是什么?一张“施工图纸”
比特流,英文叫 Bitstream。说白了,就是一长串二进制数据。它包含了配置 FPGA 内部所有资源所需的信息。
你可以把它想象成一张巨大的、细到每个晶体管开关的“施工图纸”。这张图纸告诉 FPGA:
- 每个 LUT 的查找表内容应该是什么(比如实现一个与门,还是或门)。
- 每个互连开关是闭合还是断开(决定了信号走哪条路)。
- 每个 IO 引脚是输入、输出还是双向,以及电平标准是什么。
- Block RAM 的初始数据是什么。
- DSP 模块的工作模式是什么。
不同的 FPGA 厂商,比特流的格式完全不同。Xilinx 有 Xilinx 的格式,Altera(现 Intel)有 Altera 的格式。甚至同一厂商的不同系列,比特流结构也可能天差地别。我刚开始做逆向时,就吃过这个亏——拿着 Xilinx 7 系列的经验去分析 Spartan-6,结果发现很多配置位的位置完全对不上。
一个典型的比特流文件,通常包含以下几个部分:
| 部分 | 说明 |
|---|---|
| 同步头 | 用于标识比特流的开始,通常是固定的魔数(Magic Number)。比如 Xilinx 的同步头是 0xAA995566。 |
| 配置命令 | 包含一些控制指令,比如复位、初始化、设置配置模式等。 |
| 配置数据 | 这是比特流的主体,包含了所有逻辑单元、互连、IO 的配置信息。数据量最大,也是逆向分析的重点。 |
| CRC 校验 | 用于验证比特流在传输或存储过程中是否损坏。FPGA 加载时会计算 CRC,如果不匹配,会报错并停止加载。 |
| 同步尾 | 标识比特流的结束。 |
个人经验: 拿到一个未知的比特流文件,第一步就是找同步头。用十六进制编辑器打开,搜索 AA 99 55 66(Xilinx)或 FF FF FF FF(Altera),基本就能定位到配置数据的起始位置。这是我每次逆向的“起手式”。
1.3 比特流在 FPGA 启动中的作用:从“白板”到“电路”
FPGA 是 SRAM 工艺的,这意味着它掉电后配置就丢了。每次上电,它都是一块“白板”,需要重新加载比特流才能变成你想要的电路。
这个过程,我称之为“FPGA 的觉醒仪式”。大致分三步:
- 初始化阶段:FPGA 上电后,内部电路开始复位。它会检查配置模式引脚(比如是主 SPI 模式、从串模式还是 JTAG 模式),然后准备好接收数据。这个阶段,所有 IO 都处于高阻态,芯片是“安静”的。
- 配置阶段:FPGA 开始从外部存储器(如 SPI Flash)或主机(如 CPU)读取比特流。数据按帧(Frame)为单位,逐帧写入内部的配置存储器。每一帧对应芯片上的一小片区域。我记得有一次调试,发现配置到一半卡住了,最后定位是 SPI Flash 的时钟频率太高,信号质量不行。降频后问题解决。
- 启动阶段:所有配置数据加载完成后,FPGA 会检查 CRC。如果正确,它会释放内部的全局复位信号,IO 开始按照配置工作,逻辑电路开始运行。这时候,你的设计才算真正“活”了。
整个启动过程,从几毫秒到几百毫秒不等,取决于比特流的大小和配置时钟的速度。
避坑指南: 我曾经在一个项目里,为了追求启动速度,把配置时钟设得很高。结果发现,部分芯片在高温下配置会失败。后来查资料才知道,配置时钟的频率不能超过芯片手册规定的最大值,而且要考虑 PCB 走线的信号完整性。所以,别为了快而牺牲稳定性。
1.4 知识体系:一张图看懂本章核心
为了让你更直观地理解本章的知识结构,我画了一张图。它把 FPGA 架构、比特流定义和启动流程串在了一起。
这张图从左到右,清晰地展示了三者之间的关系。FPGA 的硬件架构是舞台,比特流是剧本,启动流程就是演员上台表演的过程。搞懂这三者,你就拿到了逆向比特流的“入场券”。
我的建议: 初学者不要急着去分析复杂的比特流。先找一块开发板,用厂商工具生成一个简单的 LED 闪烁工程,然后导出比特流。用十六进制编辑器打开,对照着芯片手册,尝试找到同步头和配置数据的位置。这一步走通了,后面就顺了。
公众号:蓝海资料掘金营,微信 deep3321