目录
1、结构
dtb结构由一个小的报头和三个大小可变的部分组成:内存预留块,结构块和字符串块。 这些应该按这个顺序出现在扁平的设备树中。 因此,设备树结构作为一个整体,当以地址载入内存时,将类似于下图的图(较低的地址位于图的顶部)。
注: 内存预留块可能不存在,尽管在某些情况下可能需要它们来满足单个块的对齐约束。
2、dtb报头
所有报头字段都是32位整数,以大端格式存储 。
struct fdt_header { uint32_t magic; uint32_t totalsize; uint32_t off_dt_struct; uint32_t off_dt_strings; uint32_t off_mem_rsvmap; uint32_t version; uint32_t last_comp_version; uint32_t boot_cpuid_phys; uint32_t size_dt_strings; uint32_t size_dt_struct; };
magic |
此字段应包含值0xd00dfeed |
totalsize |
包含devicetree数据结构的总大小(以字节为单位)。这个大小应包含所有结构的各个部分(报头,内存预留块,结构块和字符串块),以及块之间或最后一块之后的任何空闲空间间隙 |
off_dt_struct | 结构块的偏移量(从报头开始的字节偏移量)。 |
off_dt_strings | 字符串块的偏移量(从报头开始的字节偏移量)。 |
off_mem_rsvmap |
内存预留块的偏移量(从报头开始的字节偏移量)。 |
version | 该dtb的版本 |
last_comp_version |
兼容版本信息(此字段应包含设备树数据结构的最低版本,使用的版本与之向后兼容)。 |
boot_cpuid_phys |
这个字段应该包含系统启动CPU的物理ID。 它应该与设备树中CPU节点的reg属性中给定的物理ID相同。 |
size_dt_strings |
该字段应包含设备树blob的字符串块部分的字节长度。 |
size_dt_struct | 该字段应包含设备树blob的结构块部分的字节长度 |
3、内存预留块
内存预留块向客户端程序提供物理内存中被预留的区域列表; 也就是说,它不应用于一般内存分配。 它用于保护重要的数据结构不被客户机程序覆盖。
3.1、结构
内存预留块由一个64位大端整数对的列表组成。
struct fdt_reserve_entry { uint64_t address; uint64_t size; };
每一对都给出一个预留内存区域的物理地址和字节大小。 这些给定的区域互不重叠。 内存预留块列表以一个地址和大小都等于0的条目结束。
注:内存预留块由多个uint64_t组成。
4、结构块
结构块描述了设备树本身的结构和内容。 它由带有数据的标记序列组成,这些标记被组织成一个线性树结构。
FDT_BEGIN_NODE(0x00000001) | 标记一个节点表示的开始。 它后面应该有节点的单元名作为额外的数据(即后跟设备节点名称)。 名称存储为一个以空字符结束的字符串,并应包括单元地址(如果有的话)。 如果需要对齐,节点名后面跟着置零填充字节,然后是下一个令牌(可以是除FDT_END之外的任何令牌)。 |
FDT_END_NODE | 标记节点表示的结束。 这个令牌没有额外的数据; 所以紧随其后的是下一个token(可以是除FDT_PROP之外的任何令牌)。 |
FDT_PROP |
标志着设备树中一个属性表示的开始。 其后应附有描述该属性的额外数据。 这个数据首先由属性的长度和名称组成(这个结构中的两个字段都是32位的大端整数)
len以字节为单位给出了属性值的长度(可以是0,表示属性为空) nameoff在字符串块中给出了一个偏移量,在该块中,属性的名称被存储为一个以空字符结束的字符串。 |
FDT_NOP | 将被任何解析设备树的程序忽略。 这个token没有额外的数据; 因此,紧跟其后的是下一个token(可以是任何有效的token)。 树中的属性或节点定义可以被FDT_NOP标记覆盖,从而将其从树中删除,而不需要在devicetree blob中移动树表示的其他部分 |
FDT_END | 标记结构块的结束。 FDT_END token应该只有一个,并且应该是结构块中的最后一个token。 它没有额外的数据; 因此FDT_END标记后面紧接的字节已经从结构块的开始处偏移,该偏移量等于devicetree blob报头中size_dt_struct字段的值。 |
4.2、树结构
设备树结构被表示为一个线性树:每个节点以FDT_BEGIN_NODE token开始,以FDT_END_NODE token结束。 节点的属性和子节点(如果有的话)在FDT_END_NODE之前表示,因此这些子节点的FDT_BEGIN_NODE和FDT_END_NODE token被嵌套在父节点的token中。
结构块作为一个整体由根节点的表示(它包含所有其他节点的表示)组成,后面跟着一个FDT_END标记,表示结构块作为一个整体的结束。
更准确地说,每个节点的表示由以下组件组成:
• (可选)任意数量的FDT_NOP tokens
• FDT_BEGIN_NODE token
—节点名以空字符结尾
—[置零填充字节对齐到4字节边界]
• 对于节点的每个属性:
—(可选)任意数量的FDT_NOP tokens
—FDT_PROP token
—[置零填充字节对齐到4字节边界]
• 描述子节点结束
—(可选)任意数量的FDT_NOP tokens
—FDT_END_NODE token
5、字符串块
字符串块包含设备树中使用的所有属性名称的字符串。这些以空结尾的字符串被简单地连接在一起,并由结构块中的偏移量引用到字符串块中。
注:字符串块没有对齐约束,可以出现在设备树块开始的任意偏移位置 !
5.1、为什么存在单独的字符串块
原因是为了节省内存空间。在设备树文件中,有很多个节点都有相同的属性名称(如compatible),这些相同名字的字符串只需保留一份。通过在字符串块中的偏移量即可获取到。
6、对齐
内存预留块应该对齐到8字节的边界,而结构块应该对齐到4字节的边界 。
7、例子
/dts-v1/; / { model = "dtb"; compatible = "abc,666", "ABC,999"; status = "okay"; node1 { str = "helloWorld"; }; node2 { val = <100 200>; }; };
7.1、报头
magic | 魔数magic,0xd00dfeed。 |
totalsize | 总字节数,0x000000f4。 |
off_dt_struct | 结构块的偏移量,0x00000038。 |
off_dt_strings | 字符串块的偏移量,0x000000d4。 |
off_mem_rsvmap |
内存预留块的偏移量,0x00000028。 |
version | 该dtb的版本为17版本,0x00000011。 |
last_comp_version |
兼容16版本信息,0x00000010,即兼容16版本的设备树。 |
boot_cpuid_phys |
系统启动CPU的物理ID,0x00000000。 |
size_dt_strings |
devicetree blob的字符串块部分的字节长度,0x00000020 。 |
size_dt_struct | devicetree blob的结构块部分的字节长度 ,0x0000009c。 |
7.2、内存预留块
内存预留块:off_mem_rsvmap(0x00000028)–off_dt_struct(0x00000038)
内存预留块格式如下:
struct fdt_reserve_entry { uint64_t address; uint64_t size; };
地址和大小都为0,表示内存预留块结束(此例未定义内存预留块内容)。
7.3、结构块
结构块偏移:off_dt_struct(0x00000038)
结构块大小:size_dt_struct(0x0000009c)
7.3.1、树形结构
FDT_BEGIN_NODE(0x0001)标记一个节点表示的开始,FDT_END_NODE(0x0002)标记节点表示的结束,FDT_END(0x0009)标记结构块的结束。
/根设备节点
–node1设备节点
–node2设备节点
7.3.2、属性1
token | FDT_PROP(0x00000003) |
属性值长度 | 0x00000004 |
属性名称在字符串块的偏移 | 0x00000000 |
属性值 | “dtb” |
属性名称 | “model” |
7.3.3、属性2
token | FDT_PROP(0x00000003) |
属性值长度 | 0x00000010 |
属性名称在字符串块的偏移 | 0x00000006 |
属性值 | “abc,666”, “ABC,999” |
属性名称 | compatible |
7.3.4、属性3
token | FDT_PROP(0x00000003) |
属性值长度 | 0x00000005 |
属性名称在字符串块的偏移 | 0x00000011 |
属性值 | “okay” |
属性名称 | status |
7.3.5、属性4
token | FDT_PROP(0x00000003) |
属性值长度 | 0x0000000b |
属性名称在字符串块的偏移 | 0x00000018 |
属性值 | “helloWorld” |
属性名称 | status |
7.3.6、属性5
token | FDT_PROP(0x00000003) |
属性值长度 | 0x00000008 |
属性名称在字符串块的偏移 | 0x0000001c |
属性值 | <100 200> |
属性名称 | val |
7.4、字符串块
字符串块偏移:off_dt_strings(0x000000d4)
字符串块大小:size_dt_strings(0x00000020)
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/233771.html原文链接:https://javaforall.net