08、dtb 文件格式讲解

一、简介
Device Tree文件有两种格式:dts和dtsi。dts是主配置文件,dtsi是被包含的公共文件,它们都是人类可读的文本文件。但U-Boot和Linux内核无法直接识别这些文本文件,必须将它们转换为二进制格式的dtb文件才能被系统识别。
转换工具是dtc(Device Tree Compiler)。Linux系统中,你可以在源码的scripts/dtc目录找到它的源代码。如果需要单独安装,可以直接通过命令sudo apt-get install device-tree-compiler安装dtc工具。安装完成后,用dtc将dts文件编译成dtb文件即可。
dtc工具的使用方法是:
dtc –I dts –O dtb –o xxx.dtb xxx.dts反过来即可生成dts文件
dtc –I dtb –O dts –o xxx.dts xxx.dtb二、Device Tree头信息
提供了一个fdtdump的工具,可以dump dtb文件,方便查看信息。

以上信息便是Device Tree文件头信息,存储在dtb文件的开头部分。在Linux内核中使用struct fdt_header结构体描述。struct fdt_header结构体定义在scripts\dtc\libfdt\fdt.h文件中。
struct fdt_header {
fdt32_t magic; /* magic word FDT_MAGIC */
fdt32_t totalsize; /* total size of DT block */
fdt32_t off_dt_struct; /* offset to structure */
fdt32_t off_dt_strings; /* offset to strings */
fdt32_t off_mem_rsvmap; /* offset to memory reserve map */
fdt32_t version; /* format version */
fdt32_t last_comp_version; /* last compatible version */
/* version 2 fields below */
fdt32_t boot_cpuid_phys; /* Which physical CPU id we're
booting on */
/* version 3 fields below */
fdt32_t size_dt_strings; /* size of the strings block */
/* version 17 fields below */
fdt32_t size_dt_struct; /* size of the structure block */
};2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
三、Device Tree文件结构
Device Tree源文件的结构分为header、fill_area、dt_struct及dt_string四个区域。fill_area区域填充数值0。

节点(node)信息使用struct fdt_node_header结构体描述。属性信息使用struct fdt_property结构体描述。各个结构体信息如下:
struct fdt_node_header {
fdt32_t tag;
char name[0];
};
struct fdt_property {
fdt32_t tag;
fdt32_t len;
fdt32_t nameoff;
char data[0];
};2
3
4
5
6
7
8
9
10
11
struct fdt_node_header描述节点信息,tag是标识node的起始结束等信息的标志位,name指向node名称的首地址。tag的取值如下:
#define FDT_BEGIN_NODE 0x1 /* Start node: full name */
#define FDT_END_NODE 0x2 /* End node */
#define FDT_PROP 0x3 /* Property: name off,
size, content */
#define FDT_NOP 0x4 /* nop */
#define FDT_END 0x92
3
4
5
6
FDT_BEGIN_NODE和FDT_END_NODE分别标记一个节点的开始和结束,FDT_PROP用来表示节点的属性,FDT_END则代表整个设备树文件的结尾。
每个节点的起始位置都用FDT_BEGIN_NODE标记,节点内的属性都由FDT_PROP开头。描述属性时使用struct fdt_property结构:
- 标识符tag固定为FDT_PROP
- 长度len记录属性值的字节数(包含结尾的空字符)
- 名称偏移nameoff指向属性名在字符串池(off_dt_strings)中的位置
这样就能清晰区分节点结构和属性信息的位置关系了。
