第二章:FPGA基础与比特流结构

做芯片逆向这么多年,我接触过不少FPGA项目。说实话,很多人一上来就盯着比特流文件猛看,结果连FPGA内部长什么样都没搞清楚。这就像你要拆解一台发动机,却不知道气缸和活塞的位置——肯定不行。

所以这一章,我们先打好基础。我会带你看看FPGA内部到底有哪些关键部件,比特流文件的结构又是怎么组织的。嗯,这些东西搞明白了,后面逆向的时候你才能游刃有余。

2.1 FPGA内部架构:四个核心部件

FPGA说白了就是一块可以反复编程的芯片。它的内部由大量可配置的逻辑单元组成。我个人习惯把FPGA的架构想象成一个乐高积木平台——你可以随意搭建你想要的数字电路。

核心部件有四个,我一个个说。

2.1.1 LUT(查找表)

LUT是FPGA最基础的逻辑单元。它本质上是一个小型的RAM,用来实现任意布尔函数。举个例子,一个4输入的LUT,可以看作是一个16×1的存储器。你输入4位地址,它输出1位数据。

我在项目中遇到过一件事:有次逆向一个通信芯片,发现对方用LUT实现了复杂的CRC校验。当时我盯着比特流看了半天,才意识到那些看似随机的配置位,其实就是在定义LUT的查找表内容。

关键点: LUT的配置位直接决定了逻辑功能。逆向时,提取LUT的配置内容,就能还原出原始的逻辑表达式。

2.1.2 BRAM(块RAM)

BRAM是FPGA内部的存储资源。它不像LUT那样做逻辑运算,而是专门用来存数据。常见的BRAM大小是18Kb或36Kb,可以配置成不同的位宽和深度。

你想想看,如果芯片里需要缓存数据、做FIFO、或者存储查找表,BRAM就是首选。我记得有一次逆向一个视频处理芯片,发现它用了大量BRAM做行缓冲。通过分析比特流中BRAM的初始化数据,我直接还原出了整张颜色校正表。

资源类型 典型容量 主要用途
LUT 4-6输入 逻辑运算、小规模存储
BRAM 18Kb / 36Kb 数据缓存、FIFO、ROM
DSP 25×18 乘法器 乘加运算、滤波
IO 可配置电平标准 外部信号接口

2.1.3 DSP(数字信号处理单元)

DSP单元是专门做算术运算的。它包含乘法器、加法器和累加器。普通的LUT也能做乘法,但效率低、占资源。DSP就是干这个的——又快又省。

我建议你在逆向时特别关注DSP的配置。因为很多算法(比如FIR滤波器、FFT)都会用到DSP。通过分析DSP的配置模式,你往往能推断出芯片在做什么样的数学运算。

2.1.4 IO(输入输出单元)

IO单元负责芯片和外部世界的通信。它支持各种电平标准,比如LVCMOS、LVDS、SSTL等。每个IO引脚都可以独立配置。

嗯,这里要注意:IO的配置信息在比特流中通常比较分散。我曾经花了两天时间,才从一份比特流中定位到某个引脚的输出使能位。所以逆向时,建议先搞清楚IO的配置规律。

2.2 比特流文件的物理结构

比特流文件,就是用来配置FPGA的二进制文件。不同厂商的格式略有差异,但核心思想是一样的——把配置数据按一定顺序组织起来,然后写入FPGA的配置存储器。

以Xilinx的比特流为例,它的结构大致如下:

+------------------+
|  同步头 (Sync)    |  // 0xAA995566
+------------------+
|  命令包 (Packet)  |  // 包含类型、操作码、数据
+------------------+
|  配置数据 (Data)  |  // 帧数据,按列组织
+------------------+
|  循环冗余校验     |  // CRC校验值
+------------------+
|  结束标志         |  // 0x20000000
+------------------+

我个人习惯先解析同步头。同步头是固定的,Xilinx的是0xAA995566,Altera的是0xFF0000FF。找到同步头,就找到了比特流的起点。

小技巧: 解析比特流时,可以用Hex编辑器先搜索同步头。如果找不到,可能是文件被加密或压缩了。我遇到过几次这种情况,后来发现是厂商加了自定义的头部。

2.3 配置帧(Configuration Frame)的概念

配置帧是比特流中最核心的概念。FPGA的配置存储器是按帧组织的。每一帧对应芯片上的一列逻辑资源。

为什么会这样设计?因为FPGA的配置数据量很大(动辄几十Mb),如果按位寻址,地址空间会爆炸。按帧组织,可以大大简化寻址逻辑。

每一帧包含的信息包括:

  • LUT的查找表内容
  • BRAM的初始化数据
  • DSP的配置模式
  • IO的电平标准和方向
  • 布线开关的状态

我记得有一次逆向一个Xilinx Kintex-7的比特流。它的配置帧大小是101个字(每个字32位)。通过逐帧解析,我成功提取出了所有LUT的配置内容。嗯,这个过程很繁琐,但结果非常值得。

警告: 不同型号的FPGA,帧大小和帧数量都不一样。比如Spartan-6的帧大小是65个字,而Virtex-7是101个字。逆向前一定要先查清楚目标芯片的帧参数。

2.4 知识体系总览

下面这张图,是我自己整理的FPGA逆向知识体系。你可以把它当作一个路线图。

FPGA逆向知识体系 FPGA内部架构 LUT BRAM DSP IO 比特流文件结构 同步头 命令包 配置数据 CRC校验 结束标志 配置帧(Configuration Frame) LUT配置 BRAM初始化 DSP模式 IO配置 布线 逆向目标:提取逻辑功能、还原电路结构

从这张图你可以看到,整个逆向过程是层层递进的。先搞懂FPGA内部有什么资源,再理解比特流怎么组织这些资源的配置信息,最后深入到配置帧级别,提取出每个逻辑单元的配置数据。

我个人觉得,配置帧是整条链路中最关键的一环。你只要掌握了帧的结构,就能像庖丁解牛一样,把比特流拆解得清清楚楚。

我的建议: 刚开始接触比特流逆向时,不要贪多。先找一个小型FPGA的比特流文件,比如Spartan-6的,手动解析几帧。等你熟悉了帧的结构,再去看大型芯片的比特流,会轻松很多。

好了,这一章的内容就到这里。FPGA的基础架构和比特流结构,是后续所有逆向工作的基石。你把这些搞明白了,后面讲配置帧解析、逻辑提取的时候,才能跟得上节奏。


公众号:蓝海资料掘金营,微信deep3321