点击蓝字 关注我们
xclbin文件概述
xclbin全称为Xilinx Container Binary,是Xilinx FPGA开发工具链(Xilinx Vivado®)生成的,用于描述FPGA硬件逻辑与软件接口的二进制文件。它不仅仅包含了FPGA的比特流(bitstream),即用于配置FPGA硬件的二进制数据,还封装了与FPGA应用紧密相关的各种资源、配置文件和元数据。这些元素共同构成了一个完整的FPGA应用程序包,使得开发者能够轻松地将自己的设计部署到Xilinx FPGA上。最近我们在调研AMD的NPU架构时发现,其底层架构也采用了类似FPGA的结构,并且使用xclbin作为其应用程序包。为了能更深入的探索,我们尝试对xclbin文件进行解析。
xclbin文件结构解析
xclbin文件格式属于私有格式,Xilinx公司没有对其进行任何文档化的描述,经过对网络上能找到的大部分信息进行检索后,我们发现xilinx公司在Github上开源了一套linux的npu支持框架,其中包含了部分xclbin的文件解析方法,经过研究和整理,我们完成了对xclbin文件的解析工作,并编写了针对性的010edit脚本。
xclbin文件由多个部分组成,包括Header、section、metadata和signature等。其各个节会相互引用或嵌套。
1
xclbin文件以axlf开头,axlf节的大小为496字节,包含如下信息:
struct axlf {
char m_magic[8]; /* Should be "xclbin2 " */
int32_t m_signature_length; /* Length of the signature. -1 indicates no signature */
unsigned char reserved[28]; /* Note: Initialized to 0xFFs */
unsigned char m_keyBlock[256]; /* Signature for validation of binary */
uint64_t m_uniqueId; /* axlf's uniqueId, use it to skip redownload etc */
struct axlf_header m_header; /* Inline header */
struct axlf_section_header m_sections[1]; /* One or more section headers follow */
};
axlf节包含axlf_header和axlf_section_header两个部分,axlf_header包含axlf_section_header的个数,axlf_section_header包含section的类型和section的大小。
struct axlf_section_header {
uint32_t m_sectionKind; /* Section type */
char m_sectionName[16]; /* Examples: "stage2", "clear1", "clear2", "ocl1", "ocl2, "ublaze", "sched" */
uint64_t m_sectionOffset; /* File offset of section data */
uint64_t m_sectionSize; /* Size of section data */
};
struct axlf_header {
uint64_t m_length; /* Total size of the xclbin file */
uint64_t m_timeStamp; /* Number of seconds since epoch when xclbin was created */
uint64_t m_featureRomTimeStamp; /* TimeSinceEpoch of the featureRom */
uint16_t m_versionPatch; /* Patch Version */
uint8_t m_versionMajor; /* Major Version - Version: 2.1.0*/
uint8_t m_versionMinor; /* Minor Version */
uint16_t m_mode; /* XCLBIN_MODE */
uint16_t m_actionMask; /* Bit Mask */
unsigned char m_interface_uuid[16]; /* Interface uuid of this xclbin */
unsigned char m_platformVBNV[64]; /* e.g. xilinx:xil-accel-rd-ku115:4ddr-xpr:3.4: null terminated */
union {
char m_next_axlf[16]; /* Name of next xclbin file in the daisy chain */
xuid_t uuid; /* uuid of this xclbin*/
};
char m_debug_bin[16]; /* Name of binary with debug information */
uint32_t m_numSections; /* Number of section headers */
};
拿到section大小后,我们通过遍历axlf_section_header数组就可以获取到xclbin中的各个子节点的信息,通过sectionKind就可以知道该节点的类型,通过sectionOffset和sectionSize就可以知道该节点的数据在文件中的位置和大小。
sectionKind类型包括以下几种:
enum axlf_section_kind {
BITSTREAM = 0,
CLEARING_BITSTREAM = 1,
EMBEDDED_METADATA = 2,
FIRMWARE = 3,
DEBUG_DATA = 4,
SCHED_FIRMWARE = 5,
MEM_TOPOLOGY = 6,
CONNECTIVITY = 7,
IP_LAYOUT = 8,
DEBUG_IP_LAYOUT = 9,
DESIGN_CHECK_POINT = 10,
CLOCK_FREQ_TOPOLOGY = 11,
MCS = 12,
BMC = 13,
BUILD_METADATA = 14,
KEYVALUE_METADATA = 15,
USER_METADATA = 16,
DNA_CERTIFICATE = 17,
PDI = 18,
BITSTREAM_PARTIAL_PDI = 19,
PARTITION_METADATA = 20,
EMULATION_DATA = 21,
SYSTEM_METADATA = 22,
SOFT_KERNEL = 23,
ASK_FLASH = 24,
AIE_METADATA = 25,
ASK_GROUP_TOPOLOGY = 26,
ASK_GROUP_CONNECTIVITY = 27,
SMARTNIC = 28,
AIE_RESOURCES = 29,
OVERLAY = 30,
VENDER_METADATA = 31,
AIE_PARTITION = 32,
IP_METADATA = 33,
AIE_RESOURCES_BIN = 34,
};
通过这些信息,我们就可以确定xclbin文件中各个子节点的类型和大小,并进一步解析。接下来我们就针对目前收集到的npu相关的文件进行解析。
2
由于xclbin的所有结构都没有文档信息,所以其中子节点的功能都是靠xilinx代码中的命名信息进行推测的,下面章节的内容基本上都是作者主观的一些想法,仅供参考。
MEM_TOPOLOGY望文生义是定义了FPGA内存的详细信息,包含FPGA内存的类型、起始地址和大小,节包含如下信息:
struct mem_data {
uint8_t m_type; // enum corresponding to mem_type.
uint8_t m_used; // if 0 this bank is not present
uint8_t padding[6]; // 8 Byte alignment padding (initialized to zeros)
union {
uint64_t m_size; // if mem_type DDR, then size in KB;
uint64_t route_id; // if streaming then "route_id"
};
union {
uint64_t m_base_address; // if DDR then the base address;
uint64_t flow_id; // if streaming then "flow id"
};
unsigned char m_tag[16]; // DDR: BANK0,1,2,3, has to be null terminated; if streaming then stream0, 1 etc
};
struct mem_topology {
int32_t m_count; //Number of mem_data
struct mem_data m_mem_data[1]; //Should be sorted on mem_type
};
3
IP核是在集成电路的可重用设计方法学中,指某一方提供的、形式为逻辑单元、芯片设计的可重用模块。它通常已经通过了设计验证,设计人员以IP核为基础进行设计,可以缩短设计所需的周期。IP核是一段具有特定电路功能的硬件描述语言程序,该程序与集成电路工艺无关,可以移植到不同的半导体工艺中去生产集成电路芯片。IP_LAYOUT节点包含FPGA中各个IP核的基础,包含IP核的名称、起始地址和类型等,节包含如下信息:
struct ip_data {
uint32_t m_type; //map to IP_TYPE enum
union {
uint32_t properties; // Default: 32-bits to indicate ip specific property.
// m_type: IP_KERNEL
// m_int_enable : Bit - 0x0000_0001;
// m_interrupt_id : Bits - 0x0000_00FE;
// m_ip_control : Bits = 0x0000_FF00;
// properties is also used for ps kernel (i.e. -add-pskernel)
// PS Kernels
// m_type: IP_PS_KERNEL
struct {
uint16_t m_subtype : 2; // Bits - 0x0003 - PS_SUBTYPE enum values
uint16_t : 2; // Bits - 0x000C - Future use
uint16_t m_functional : 2; // Bits - 0x0030 - PS_FUNCTIONAL enum values
uint16_t : 10; // Bits - 0xFFC0 - Future use
uint16_t m_kernel_id : 12; // Bits - 0x0FFF
uint16_t : 4; // Bits - 0xF000 - Future use
} ps_kernel;
struct { // m_type: IP_MEM_*
uint16_t m_index;
uint8_t m_pc_index;
uint8_t unused;
} indices;
};
uint64_t m_base_address;
uint8_t m_name[64]; //eg Kernel name corresponding to KERNEL instance, can embed CU name in future.
};
往期精彩合集
● Web安全之SRI(Subresource Integrity子资源完整性)详解
● 联想GIC全球安全实验室受邀参加行业研讨会,分享红蓝对抗思想在产品安全中的应用
● 联想全球安全实验室受邀参加2024年AIGC数据应用大会,共谋数据合规与网络安全应对策略
长
按
关
注
联想GIC全球安全实验室(中国)
原文始发于微信公众号(联想全球安全实验室):探索FPGA的xclbin文件格式