Linux设备树学习2 - DTB文件格式

article/2025/10/24 6:46:03

一. DTB文件简介

        DTB文件是由DTS文件通过dtc命令编译生成的二进制文件。DTS文件不能直接被内核解析,需要编译成DTB文件才可以直接被内核识别并解析使用的。

二. DTB文件内容布局

                 从上图可以看出,DTB由四个部分组成,分别是struct fdt_headermemory reservationstructure blockstrings block,free space用于填充,使以上四个块的数据能满足四字节对齐,所以free space并不总是会显示出来。下面会详细介绍DTB文件各个部分。

三. FDT Header介绍

        struct fdt_header的布局可以使用一个C语言结构体定义,占用的内存大小为40字节,如下

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;
};

示例:

00000000  d0 0d fe ed 00 00 1a 77  00 00 00 38 00 00 18 60  |.......w...8...`|
00000010  00 00 00 28 00 00 00 11  00 00 00 10 00 00 00 00  |...(............|
00000020  00 00 02 17 00 00 18 28                           |.......(........|

magic :该字段应该被设置成0xd00dfeed,字节序是大端字节序

totalsize :DTB文件的总大小,示例中为0x00001a77

off_dt_struct :structure block相对于DTB文件头的偏移的字节数,示例中为0x00000038

off_dt_strings :strings block相对于DTB文件头的偏移的字节数,示例中为0x00001860

off_mem_rsvmap :memory reservation相对于DTB文件头的字节数,示例中为0x00000028

version :DTB的版本号,示例中为0x00000011

last_comp_version :DTB的上一个版本,示例中为0x00000010

boot_cpuid_phys :保存系统CPU的ID号,示例中为0x00

size_dt_strings :strings block的大小,示例中为0x00000217

size_dt_struct :structure block的大小,示例中为0x00001828

四. Memory Reservation介绍

        memory reservation指定的内存范围将会被保留,它不能被一般的内存分配函数使用,防止这块内存内的重要数据被内核破坏。memory reservation也可以用C语言的结构体表示,如下

struct fdt_reserve_entry {uint64_t address;uint64_t size;
};

        struct fdt_reserve_entry占用16字节大小,address和size都由u64数表示。

五. Structure Block介绍

        structure block由五个标识包含设备树的一些数据,形成一个树形结构,五个标识分别如下 

FDT_BEGIN_NODE (0x00000001) :表示一个设备节点的开始。接下来跟着设备节点的名字,设备备节点名字如果有unit-address,需要加上去,节点名字最后以NULL结尾。如果结尾没有4字节对齐,需要填充0x00,保证4字节对齐。

FDT_END_NODE (0x00000002) :表示一个设备节点的结束。它的后面不用跟数据,通常是跟下一个标识,除了FDT_DROP。

示例

DTS代码片段

cpus {cpu@0 {compatible = "mips,mips24KEc";};
};

DTB代码片段

000000b0              00 00 00 01  63 70 75 73 00 00 00 00  |........cpus....|
000000c0  00 00 00 01 63 70 75 40  30 00 00 00 00 00 00 03  |....cpu@0.......|
000000d0  00 00 00 0f 00 00 00 1b  6d 69 70 73 2c 6d 69 70  |........mips,mip|
000000e0  73 32 34 4b 45 63 00 00  00 00 00 02 00 00 00 02  |s24KEc..........|

        从上面的代码可知,包含了两个device_node,分别是cpus和cpu@0,cpu@0是cpus的子节点,所以代码中有两个FDT_BEGIN_NODE (0x00000001),和FDT_END_NODE (0x00000002)。FDT_BEGIN后跟着节点名称。从DTB的组织方式也可以看出structure block是以树状层次结构布局的。

FDT_DROP (0x00000003) :表示一个属性的开始。后面需要跟一个属性名的长度和偏移量,再后面跟属性的值,属性的长度和偏移量可以用C语言结构体表示

struct {uint32_t len;uint32_t nameoff;
}

        len表示此结构后跟的属性值的长度,NULL也包含在内,nameoff表示属性名在strings block中偏移量。示例如下

00000090  00 00 00 03 00 00 00 15  00 00 00 26 57 6f 6f 79  |...........&Wooy|
000000a0  61 20 49 4f 54 20 53 6d  61 72 74 20 37 36 32 30  |a IOT Smart 7620|
000000b0  00 00 00 00                                       |....            |

节选strings block

00001860  23 61 64 64 72 65 73 73  2d 63 65 6c 6c 73 00 23  |#address-cells.#|
00001870  73 69 7a 65 2d 63 65 6c  6c 73 00 63 6f 6d 70 61  |size-cells.compa|
00001880  74 69 62 6c 65 00 6d 6f  64 65 6c 00 62 6f 6f 74  |tible.model.boot|
00001890  61 72 67 73 00 23 69 6e  74 65 72 72 75 70 74 2d  |args.#interrupt-|
000018a0  63 65 6c 6c 73 00 69 6e  74 65 72 72 75 70 74 2d  |cells.interrupt-|
000018b0  63 6f 6e 74 72 6f 6c 6c  65 72 00 6c 69 6e 75 78  |controller.linux|
000018c0  2c 70 68 61 6e 64 6c 65  00 72 65 67 00 72 61 6e  |,phandle.reg.ran|
000018d0  67 65 73 00 69 6e 74 65  72 72 75 70 74 2d 70 61  |ges.interrupt-pa|
000018e0  72 65 6e 74 00 69 6e 74  65 72 72 75 70 74 73 00  |rent.interrupts.|

00 00 00 03 :表示FDT_DROP

00 00 00 15 :表示"Wooya IOT Smart 7620"的长度,记得结尾的NULL也计算在内

00 00 00 26 :表示"Wooya IOT Smart 7620"的属性名在strings block中的偏移,从节选的strings block可以看出属性名是"model"。

tips :结尾多出的00 00 00是为了保证4字节对齐

FDT_NOP (0x00000004) :FDT_NOP程序在解析时将被忽略,此标识不跟任何数据,只跟下一个标识。

FDT_END (0x00000009) :FDT_END表示structure block的结束,DTB文件只有一个FDT_END标识,并且是structure block的最后一个标识,所以后面跟的是strings block的开始。

根节点示例:

DTS代码片段

/ {#address-cells = <0x1>;#size-cells = <0x1>;................}

DTB代码片段

00000030                           00 00 00 01 00 00 00 00  |................|
00000040  00 00 00 03 00 00 00 04  00 00 00 00 00 00 00 01  |................|
00000050  00 00 00 03 00 00 00 04  00 00 00 0f 00 00 00 01  |................|......../* strings blcok start */
00001860  23 61 64 64 72 65 73 73  2d 63 65 6c 6c 73 00 23  |#address-cells.#|
00001870  73 69 7a 65 2d 63 65 6c  6c 73 00 63 6f 6d 70 61  |size-cells.compa|
00001880  74 69 62 6c 65 00 6d 6f  64 65 6c 00 62 6f 6f 74  |tible.model.boot|
00001890  61 72 67 73 00 23 69 6e  74 65 72 72 75 70 74 2d  |args.#interrupt-|
000018a0  63 65 6c 6c 73 00 69 6e  74 65 72 72 75 70 74 2d  |cells.interrupt-|
000018b0  63 6f 6e 74 72 6f 6c 6c  65 72 00 6c 69 6e 75 78  |controller.linux|
000018c0  2c 70 68 61 6e 64 6c 65  00 72 65 67 00 72 61 6e  |,phandle.reg.ran|

        以上DTB片段是根节点的,根节点比较特殊,根节点00 00 00 01后接着的是00 00 00 00,可以看出根节点节点名是空的,00 00 00 03后是属性值的长度为0x04,strings block中的偏移为0,值为00 00 00 01,表示#address-cells = <0x1>;后面00 00 00 03则表示#size-cells = <0x1>。

六. Strings Block介绍

        string block包含了在设备树中出现的所有的属性名,所有的名字都是以NULL结尾,structure block通过nameoff来引用其中的属性名。strings block的结尾不需要4字节对齐。

七. 总结

        本文介绍了DTB文件的四个块,分别是struct header,memory reservation,structure block,strings block,并介绍了他们的各自的组织方式。熟悉DTB的数据组织方式,是理解Linux内核解析DTB文件流程的基础,所以熟悉DTB非常的重要。


http://chatgpt.dhexx.cn/article/hd0l1ZHf.shtml

相关文章

setUserVisibleHint-- fragment真正的onResume和onPause方法

这个情况仅适合与多个fragment之间切换时统计&#xff0c;而非activity和fragment同时交互&#xff0c;因当时项目为首页4个fargment时长统计&#xff0c;因此适合&#xff0c;经下面网友评论指出&#xff0c;特在这里写出此问题&#xff0c;因最近项目较忙&#xff0c;具体情况…

onCreate与onStart区别,onStart与onResume区别

http://www.cnblogs.com/kofi1122/archive/2011/04/10/2011772.html Activity生命周期之我见 关于Activity生命周期的文章很多&#xff0c;而且大部分也说得很详细&#xff0c;所以作为关于这方面的内容我本来不想多说&#xff0c;但是大家可能跟我之前一样&#xff0c;在看这方…

Flutter BaseWidget 实现onResume、onPause()

熟读唐诗三百首&#xff0c;不会作诗也会吟。——孙洙 最近用Flutter开发的项目算是完成了开发到上线第一阶段了。任何一个项目开始了&#xff0c;若想追求的是更好&#xff0c;那么就需要下功夫对项目用户体验和代码效率深入的研究了。作为用户和产品经理、老板、UI、不懂技术…

Activity生命周期中onStart()和onResume()的区别

Activity生命周期中onStart()和onResume()的区别 在讲onStart()和onResume()的区别之前&#xff0c;必须清楚Activity的四种状态&#xff1a; 1.Running状态&#xff1a;一个新的Activity的启动入栈后&#xff0c;它在屏幕最前端&#xff0c;处于栈的最顶端&#xff0c;此时它…

android Activity的onPause()与onResume()

官方文档地址&#xff1a;http://www.android-doc.com/training/basics/activity-lifecycle/pausing.html#Resume Pause和Resume一个Activity 在一般的app使用中&#xff0c;前台的activity一般是会被视觉组件所遮住的&#xff0c;这就会导致activity的pause。举个例子&#x…

android中onResume、onPause等方法

程序正常启动&#xff1a;onCreate()->onStart()->onResume(); 正常退出&#xff1a;onPause()->onStop()->onDestory() 程序按back 退出&#xff1a; onPause()->onStop()->onDestory(),再进入&#xff1a;onCreate()->onStart()->onResume(); 程序按…

OnStart()方法和OnResume()方法的区别

文章目录 一、Activity的生命周期简述在讲onStart()和onResume()的区别之前&#xff0c;必须清楚Activity的四种状态&#xff1a; 二、OnStart()和OnResume()方法的区别区别&#xff1a; 总结 一、Activity的生命周期简述 在讲onStart()和onResume()的区别之前&#xff0c;必须…

简单介绍几种Java后台开发常用框架组合

01 前言 Java框架一直以来都是面试必备的知识点&#xff0c;而掌握Java框架&#xff0c;不管在成熟的大公司&#xff0c;快速发展的公司&#xff0c;还是创业阶段的公司&#xff0c;都能对当前正在开发中的系统有整体的认知&#xff0c;从而更好的熟悉和学习技术&#xff0c;这…

用IDEA进行Java后台开发(一)

想尝试着进行java后台开发&#xff0c;发现能找到的完整工程教程很多都是用eclipse开发的&#xff0c;于是照着搭了一套开发环境&#xff0c;也简单的写了一个测试代码&#xff0c;由于好几年没有使用eclipse了&#xff0c;快捷键实在用的费劲&#xff0c;遂找到了IDEA这个开发…

Java后台学习路线

2021.01.31.更新 2018.11.10更新&#xff0c;请看文章末尾惊喜 或者点击 https://blog.csdn.net/qq_40374604/article/details/83932163 本文摘自---https://blog.csdn.net/u014624241/article/details/52946378---感谢作者的分享 ①一段摘自知乎的文档 Java就业方向目前主…

Java后台开发一:环境搭建

很久之前就想做Java后台开发了&#xff0c;苦于一直没有找到合适的后台开发教程&#xff0c;某日发现一篇很不错的Java后台开发配置文章&#xff0c;记录如下&#xff1a; jdkeclipsesvnmavenmysqltomcat7.0sublime安装包和jar插件 配置管理工具-SVN http://download.csdn.net/…

Java后台开发知识一览

Java后台开发知识一览 1、后端 WEB服务器&#xff1a;Weblogic、Tomcat、WebSphere、JBoss、Jetty 核心框架&#xff1a;Spring Framework 分布式服务框架 Dubbo&#xff08;感谢浅浅浅丿忧伤指正&#xff09; 安全框架&#xff1a;Apache Shiro 视图框架&#xff1a;Spr…

Java后台开发常见官方网站汇总

Java后台开发常见官方网站汇总 写在前面开发工具篇JDKJavaSE开发文档Oracle数据库&#xff08;收费&#xff09;MySQL数据库&#xff08;免费&#xff09;RedisMongoDBJDBCDruid连接池ElasticsearchKibana——Elasticsearch的客户端RabbitMQMavenGitSpring Framework&#xff0…

【Java后台开发规范】--- 日志的输出

文章目录 前言其他类型的规范 日志输出过多日志重复打印批量打印日志中带方法讲故事日志跟踪其他基本要求 前言 做Java开发的&#xff0c;大多数可能都有看过阿里的Java后台开发手册&#xff0c;里面有关于Java后台开发规范的一些内容&#xff0c;基本覆盖了一些通用、普适的规…

用IDEA进行Java后台开发(二)

这篇博客接上一篇&#xff0c;用IDEA进行Java后台开发&#xff08;一&#xff09; 上一篇我们已经将工程创建完成了&#xff0c;下面我们将创建一个Servlet&#xff0c;然后本地启动tomcat后调用接口&#xff0c;返回helloWorld&#xff0c;过程如下&#xff1a; 1.在src目录…

Java后台开发入门

转载自: 梦回河口&#xff1a;http://blog.csdn.net/zxc514257857/article/details/71152003 1&#xff0c;什么是Web应用程序 Web应用程序是可以通过Web进行访问的应用程序&#xff0c;最大的好处是访问非常容易。比如淘宝、新浪、网易等门户网站   软件开发领域的三大方向…

Java后台开发:环境搭建

jdkeclipsesvnmavenmysqltomcat7.0sublime安装包和jar插件 配置管理工具-SVN http://download.csdn.net/detail/u013142781/9355417 tomcatPluginV331 http://download.csdn.net/detail/u013142781/9355409 Sublime_Text_2.0.2 http://download.csdn.net/detail/u013142781/…

【Java后台】从零开始的Java后台开发(三)

编写基础的Servlet应用程序 1 Servlet 使用Servlet需要在pom.xml中引入以下依赖&#xff1a; <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api --><dependency><groupId>javax.servlet</groupId><artifactId>javax.…

【Java后台】从零开始的Java后台开发(一)

1. 工具 tomcat 9.0.65ideal 1. Ideal新建项目 File->New->Project 主要修改如下所示几个地方&#xff0c;之后点击create按钮 创建成功后一开始的目录如下所示&#xff0c; 但先不要动项目&#xff0c;它还在后台下载一些东西&#xff0c;下载完成后&#xff0…

数据迁移,数据库迁移工具,数据库实时同步方案

SyncNavigator是一款功能强大的数据库同步软件&#xff0c;适用于SQL SERVER, MySQL&#xff0c;具有自动/定时同步数据、无人值守、故障自动恢复、同构/异构数据库同步、断点续传和增量同步等功能&#xff0c;支持Windows xp以上所有操作系统&#xff0c;适用于大容量数据库快…