Device Tree (二) - dtb格式

dtb作为二进制文件被加载到内存中,然后由内核读取并进行解析,如果对dtb文件的格式不了解,那么在看设备树解析相关的内核代码时将会寸步难行,而阅读源代码才是了解设备树最好的方式,所以,如果需要更透彻的了解设备树解析的细节,第一步就是需要了解设备树的格式。

1,DTB整体结构

经过Device Tree Compiler编译,Device Tree source file变成了Device Tree Blob(又称作flattened device tree)的格式。Device Tree Blob的数据组织如下图所示:

2,DTB header

struct fdt_header结构体的定义如下:

struct fdt_header {fdt32_t magic;             /* 用来识别DTB的。通过这个magic,kernel可以确定bootloader传递的参数block是一个DTB还是tag list,以大端模式保存 */fdt32_t totalsize;         /* 整个DTB文件的大小 */fdt32_t off_dt_struct;         /* structure block的偏移地址 */fdt32_t off_dt_strings;         /* strings block的偏移地址 */fdt32_t off_mem_rsvmap;         /* memory reservation block的偏移地址 */fdt32_t version;         /* 该DTB的版本 */fdt32_t last_comp_version;     /* 兼容版本信息 *//* version 2 fields below */fdt32_t boot_cpuid_phys;     /* 我们在哪一个CPU(用ID标识)上booting *//* version 3 fields below */fdt32_t size_dt_strings;     /* device tree strings block的size。和off_dt_strings一起确定了strings block在内存中的位置 *//* version 17 fields below */fdt32_t size_dt_struct;         /* device tree structure block的size。和和off_dt_struct一起确定了device tree structure block在内存中的位置 */
};

3,memory reserve map的格式描述

fdt_reserve_entry结构体如下:

struct fdt_reserve_entry {fdt64_t address;fdt64_t size;
};

该结构体用于表示memreserve的起始地址和内存空间的大小,它紧跟在struct fdt_header结构体后面。

这一部分的作用是告诉内核哪一些内存空间需要被保留而不应该被系统覆盖使用,因为在内核启动时常常需要动态申请大量的内存空间,只有提前进行注册,用户需要使用的内存才不会被系统征用而造成数据覆盖。

值得一提的是,对于设备树而言,即使不指定保留内存,系统也会默认为设备树保留相应的内存空间。

同时,这一部分需要64位(8字节)对齐。

例如:

kernel/arch/arm/boot/dts/rtd1195.dtsi// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
/*
* Copyright (c) 2017-2019 Andreas Färber
*//memreserve/ 0x00000000 0x0000a800; /* boot code */
/memreserve/ 0x0000a800 0x000f5800;
/memreserve/ 0x17fff000 0x00001000;#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/reset/realtek,rtd1195.h>/ {compatible = "realtek,rtd1195";interrupt-parent = <&gic>;#address-cells = <1>;#size-cells = <1>;

/memreserve/ 0x00000000 0x0000a800,fdt_reserve_entry的结构体成员address = 0x00000000,size = 0x0000a800。

4, device tree structure block的格式描述

device tree structure block区域是由若干的分片组成,每个分片开始位置都是保存了token,以此来描述该分片的属性和内容。共计有5种token:

(1)FDT_BEGIN_NODE (0x00000001)。该token描述了一个node的开始位置,紧挨着该token的就是node name(包括unit address)

(2)FDT_END_NODE (0x00000002)。该token描述了一个node的结束位置。

(3)FDT_PROP (0x00000003)。该token描述了一个property的开始位置,该token之后是两个u32的数据,分别是length和name offset。length表示该property value data的size。name offset表示该属性字符串在device tree strings block的偏移值。length和name offset之后就是长度为length具体的属性值数据。

(4)FDT_NOP (0x00000004)。

被解析设备树的程序忽略,可用于覆盖其他属性,以删除它。

(5)FDT_END (0x00000009)。该token标识了一个DTB的结束位置。

单个节点在structure block的存储格式如下图所示(子节点的存储格式也是一样):

5, device tree strings block的格式描述

在dtb中有大量的重复字符串,比如"model","compatile"等等,为了节省空间,将这些字符串统一放在某个地址,需要使用的时候直接使用索引来查看。

需要注意的是,属性部分格式为key = value,key部分被放置在strings部分,而value部分的字符串并不会放在这一部分,而是直接放在structure中。

6,dtb文件解析示例

编译生成dtb文件的源设备树test_dts.dts文件如下:

/dts-v1/;/memreserve/ 0x00000000 0x00001000;/ {compatible = "brcm,bcm2835";model = "BCM2835";#address-cells = <1>;#size-cells = <1>;chosen {stdout-path = "serial0:115200n8";};memory@80000000 {device_type = "memory";reg = <0x80000000 0x10000000>;};usbphy: phy {compatible = "usb-nop-xceiv";#phy-cells = <0>;};
};

使用如下指令生成test_dtb.dtb文件

dtc -I dts -O dtb -o test_dtb.dtb test_dts.dts

hexdump -C test_dtb.dtb 显示dtb文件的内容, device Tree的文件是以大端模式储存:

1) d0 0d fe ed magic

2) 00 00 01 a3 totalsize

3) 00 00 00 48 offdtstruct 0x48

4) 00 00 01 50 offdtstrings

5) 00 00 00 28 off memreserve map

6) 00 00 00 11 version

7) 00 00 00 10 compatible version

8) 00 00 00 00 bootcpu ID

9) 00 00 00 53 size dt strings

10) 00 00 01 08 size dt structure

11) 00 00 00 00 00 00 00 00 memreserve address

12) 00 00 00 00 00 00 10 00 memreserve size

13) 00 00 00 01 所处地址为0x48,处在structure block中,0x00000001表示设备节点的开始

14) 00 00 00 00 紧跟着的是设备节点的名字,这里是根节点,所以为0x00000000

15) 00 00 00 03 0x00000003表示的开始描述设备节点的一个属性

16) 00 00 00 0d 表示这个属性值的长度为0x0d

17) 00 00 00 00 表示这个属性的名字在strings block的偏移量是0,找到strings block的地址0x0150的地方,可知这个属性的名字是compatible

18) 62 72 63 6d 2c 62 63 6d 32 38 33 35 00 这个compatible属性的值是"brcm,bcm2835",加上字符串结束符NULL,正好是13个字节

19) 00 00 00 01 chosen节点的开始

20) 63 68 6f 73  65 6e 00 chosen节点的名字

21) 00 00 00 02 chosen节点的结束

22) 00 00 00 09 structure block的结束

23) 63 6f 6d 70 61 74 69 62  6c 65 00 属性名字:compatible

7,Device Tree文件结构

通过以上分析,可以得到Device Tree文件结构如下图所示。dtb的头部首先存放的是fdt_header的结构体信息,接着是填充区域,填充大小为off_dt_struct – sizeof(struct fdt_header),填充的值为0。接着就是struct fdt_property结构体的相关信息。最后是dt_string部分。

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

struct fdt_node_header描述节点信息,tag是标识node的起始结束等信息的标志位,name指向node名称的首地址。tag的取值如下: 

1. #define FDT_BEGIN_NODE 0x1 /* Start node: full name */
2. #define FDT_END_NODE 0x2 /* End node */
3. #define FDT_PROP 0x3 /* Property: name off, size, content */
4. #define FDT_NOP 0x4 /* nop */
5. #define FDT_END 0x9

FDT_BEGIN_NODE和FDT_END_NODE标识node节点的起始和结束,FDT_PROP标识node节点下面的属性起始符,FDT_END标识Device Tree的结束标识符。因此,对于每个node节点的tag标识符一般为FDT_BEGIN_NODE,对于每个node节点下面的属性的tag标识符一般是FDT_PROP。

描述属性采用struct fdt_property描述,tag标识是属性,取值为FDT_PROP;len为属性值的长度(包括‘\0’,单位:字节);nameoff为属性名称存储位置相对于off_dt_strings的偏移地址。

struct fdt_property {fdt32_t tag;fdt32_t len;fdt32_t nameoff;char data[0];
};

dt_struct在Device Tree中的结构如下图所示。节点的嵌套也带来tag标识符的嵌套。

参考链接:

https://blog.51cto.com/u_15169172/4065013

https://www.cnblogs.com/downey-blog/p/10485529.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/740473.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【数据结构】哈希表(Hash Table)

文章目录 一&#xff1a;哈希表&#xff08;Hash Table&#xff09;1.1 简介1.2 可以将算法思想分为两个部分1.3 相关术语1.4 性质 二&#xff1a;哈希冲突2.1 什么是哈希冲突2.2 为何要避免哈希冲突2.3 如何避免哈希冲突2.4 如何减少哈希冲突2.4.1 直接地址法2.4.1 除留余数法…

工具篇--分布式定时任务springBoot 整合 elasticjob使用(3)

文章目录 前言一、Springboot 整合&#xff1a;1.1 引入jar&#xff1a;1.2 配置zookeeper 注册中心&#xff1a;1.3 定义job 业务类&#xff1a;1.4 job 注册到zookeeper&#xff1a;1.5 项目启动&#xff1a;1.5.1 zookeeper 注册中心实例&#xff1a;1.5.2 任务执行日志输出…

Ubuntu 14.04:PaddleOCR基于PaddleServing的在线服务化部署(失败)

一、 二、安装 注&#xff1a; 安装 PaddleOCR 2.3 。 因为 PaddleOCR 2.4 的 推荐环境 PaddlePaddle > 2.1.2。 https://github.com/PaddlePaddle/PaddleOCR/blob/release/2.4/doc/doc_ch/environment.md 安装前的环境准备 在使用Paddle Serving之前&#xff0c;需要完…

数据结构和算法:复杂度分析

算法效率评估 时间效率&#xff1a;算法运行速度的快慢。 空间效率&#xff1a;算法占用内存空间的大小。 效率评估方法主要分为两种&#xff1a;实际测试、理论估算 实际测试问题&#xff1a; 1.难以排除测试环境的干扰因素。 硬件配置会影响算法的性能。需要在各种机器上进…

Web 常用的 扩展开发框架

当谈到提升浏览器功能和用户体验时&#xff0c;浏览器扩展成了一股强大的力量&#xff0c;备受用户青睐。在众多的Web扩展开发框架中&#xff0c;WXT和Plasmo凭借其丰富的工具和特性&#xff0c;以及简化的开发流程&#xff0c;成为开发者们的首选。在本文中&#xff0c;我们将…

数据分析-Pandas如何画自相关图

数据分析-Pandas如何画自相关图 数据分析和处理中&#xff0c;难免会遇到各种数据&#xff0c;那么数据呈现怎样的规律呢&#xff1f;不管金融数据&#xff0c;风控数据&#xff0c;营销数据等等&#xff0c;莫不如此。如何通过图示展示数据的规律&#xff1f; 数据表&#x…

C#,文字排版的折行问题(Word-wrap problem)的算法与源代码

1、英文的折行问题 给定一个单词序列&#xff0c;以及一行中可以输入的字符数限制&#xff08;线宽&#xff09;。 在给定的顺序中放置换行符&#xff0c;以便打印整齐。 假设每个单词的长度小于线宽。 像MS word这样的文字处理程序负责放置换行符。 这个想法是要有平衡的线条。…

专业140+总分430+西南交通大学924信号与系统考研经验电子信息与通信工程,真题,大纲,参考书

今年报考西南交通大学&#xff0c;考研分数专业课924信号与系统140&#xff0c;总分430&#xff0c;各门分数都还是比较均衡&#xff0c;经过一年的复习&#xff0c;有得有失&#xff0c;总结一下自己的复习经历&#xff0c;希望给大家有点帮助&#xff0c;在复习中做的更好&am…

钉钉平台“智”领宠物界,开启萌宠智能新时代!

在当前数字化转型的浪潮中&#xff0c;钉钉用便捷的数字化解决方案推动了宠物业界的智能升级。一家宠物用品公司采用无雀科技数字化管理系统&#xff0c;与钉钉平台结合&#xff0c;解决了小型企业普遍存在的财务管理不清晰、业务流程不规范、客户信息核对繁琐等痛点问题。 针对…

AHU 汇编 实验六

一、实验名称&#xff1a;实验6 输入一个16进制数&#xff0c;把它转换为10进制数输出 实验目的&#xff1a; 培养汇编中设计子程序的能力 实验过程&#xff1a; 源代码&#xff1a; data segmentbuff1 db Please input a number(H):$buff2 db 30,?,30 dup(?),13,10buff3 …

多维时序 | Matlab实现VMD-CNN-LSTM变分模态分解结合卷积神经网络结合长短期记忆神经网络多变量时间序列预测

多维时序 | Matlab实现VMD-CNN-LSTM变分模态分解结合卷积神经网络结合长短期记忆神经网络多变量时间序列预测 目录 多维时序 | Matlab实现VMD-CNN-LSTM变分模态分解结合卷积神经网络结合长短期记忆神经网络多变量时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介…

鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:Stepper)

步骤导航器组件&#xff0c;适用于引导用户按照步骤完成任务的导航场景。 说明&#xff1a; 该组件从API Version 8开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 子组件 仅能包含子组件StepperItem。 接口 Stepper(value?: { index?…

微信小程序小白易入门基础教程1

微信小程序 基本结构 页面配置 页面配置 app.json 中的部分配置&#xff0c;也支持对单个页面进行配置&#xff0c;可以在页面对应的 .json 文件来对本页面的表现进行配置。 页面中配置项在当前页面会覆盖 app.json 中相同的配置项&#xff08;样式相关的配置项属于 app.js…

鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:RichText)

富文本组件&#xff0c;解析并显示HTML格式文本。 说明&#xff1a; 该组件从API Version 8开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。该组件无法根据内容自适应设置宽高属性&#xff0c;需要开发者设置显示布局。 子组件 不包含子组…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的石头剪刀布手势识别系统详解(深度学习模型+UI界面代码+训练数据集)

摘要&#xff1a;本篇博客深入探讨了使用深度学习技术开发石头剪刀布手势识别系统的过程&#xff0c;并分享了完整代码。该系统利用先进的YOLOv8、YOLOv7、YOLOv6、YOLOv5算法&#xff0c;并对这几个版本进行性能对比&#xff0c;如mAP、F1 Score等关键指标。文章详细阐述了YOL…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的远距离停车位检测系统(深度学习代码+UI界面+训练数据集)

摘要&#xff1a;开发远距离停车位检测系统对于提高停车效率具有关键作用。本篇博客详细介绍了如何运用深度学习构建一个远距离停车位检测系统&#xff0c;并提供了完整的实现代码。该系统基于强大的YOLOv8算法&#xff0c;并对比了YOLOv7、YOLOv6、YOLOv5&#xff0c;展示了不…

TS271IDT运算放大器芯片中文资料PDF数据手册引脚图图片参数价格功能

产品描述&#xff1a; TS271 是一款低成本、低功耗的单通道运算放大器&#xff0c;设计用于采用单电源或双电源供电。该运算放大器采用意法半导体硅栅CMOS工艺&#xff0c;具有出色的消耗-速度比。该放大器非常适合低功耗应用。 电源可通过引脚 8 和 4 之间连接的电阻器进行外…

2024年【高压电工】考试及高压电工考试总结

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 高压电工考试考前必练&#xff01;安全生产模拟考试一点通每个月更新高压电工考试总结题目及答案&#xff01;多做几遍&#xff0c;其实通过高压电工模拟试题很简单。 1、【单选题】 为了保证频率偏差不超过规定值,必…

基于Springboot的预报名管理系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的预报名管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&a…

用miniconda建立PyTorch、Keras、TensorFlow三个环境

一、配置清华镜像conda源 由于网络问题&#xff0c;直接使用conda默认的源下载包可能会非常慢。为了解决这个问题&#xff0c;可以配置国内镜像源来加速包的下载。清华大学TUNA协会提供了一个常用的conda镜像源。下面是如何配置清华镜像源的步骤&#xff1a; 1. 配置清华conda…