设备树dtb文件的格式分析

简介: 设备树dtb文件的格式分析

参考设备树内容

/dts-v1/;
/ {
    model = "this is my devicethree!";
        #address-cells = <1>;
        #size-cells = <1>;
    chosen {
        bootargs = "root=/dev/nfs rw nfsroot=192.168.1.1 console=ttyS0,115200";
    };
    cpu: cpu@1 {
            device_type = "cpu";
            compatible = "arm,cortex-a35","arm,armv8";
            reg = <0x0 0x1>;
    };
    aliases{
        led1 = "/gpio22020101";
    };
    node1{
        #address-cells = <1>;
        #size-cells = <1>;
        gpio@22020101{
            reg=<0x20110102 0x40>;
        };
    };
    node2{
        node1-child{
            pinnum = <0 1 2 3 4>;
        };
    };
    gpio@22020101{
        reg=<0x20110101 0x40>;
        status="okay";
    };
};

编译得到dtb文件

/home/alientek/linux/IMX6ULL/linux/temp/linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek/scripts/dtc/dtc -I dts -O dtb -o my_device_tree.dtb my_device_tree.dts

使用软件查看生成的dtb文件

DTB文件格式

DTB文件格式主要分为四个部分:header(头部),memory reservation block(内存预留块),structure block(结构块),strings block(字符串块)。free space(自由空间)

不一定存在。

分布

struct fdt_header

free space

memory reservation block

free spacestructure block

free spacestrings block

free space

1.header头部

struct fdt_header {
    uint32_t magic;             /* magic word FDT_MAGIC */ // FDT_MAGIC 魔数
    uint32_t totalsize;         /* total size of DT block */ // DT块的总大小
    uint32_t off_dt_struct;         /* offset to structure */ // 结构体的偏移量
    uint32_t off_dt_strings;     /* offset to strings */ // 字符串的偏移量
    uint32_t off_mem_rsvmap;     /* offset to memory reserve map */ // 内存保留映射的偏移量
    uint32_t version;         /* format version */ // 格式版本
    uint32_t last_comp_version;     /* last compatible version */ // 最后兼容版本
    /* version 2 fields below */
    uint32_t boot_cpuid_phys;     /* Which physical CPU id we're
                        booting on */ // 我们正在启动的物理CPU ID
    /* version 3 fields below */
    uint32_t size_dt_strings;     /* size of the strings block */ // 字符串块的大小
    /* version 17 fields below */
    uint32_t size_dt_struct;     /* size of the structure block */ // 结构块的大小
};

注意:所有成员类型均为32u,为大端模式

1.magic

magic的值必须是0xd00dfeed。打开文件。

2.totalsize

totalsize表示dtb文件的大小。例子中dtb文件大小为676字节。如下图所示:

totalsize的类型为u32,,所以676字节转换成16进制是0x000002a4。打开文件dtb。

3.off_dt_struct

off_dt_struct表示structure block(结构块)在dtb文件中的偏移地址。dtb文件中off_dt_struct的值是0x00000038。

所以structure block(结构块)从下图开始

4.off_dt_strings字符串的偏移量

off_dt_strings表示(字符串块)在dtb文件中的偏移地址。dtb文件中off_dt_strings的值为0x0000024c。

所以strings block(字符串块)从下图位置开始。

5.off_mem_rsvmap 内存保留映射的偏移量

off_mem_rsvmap表示memory reservation block(内存预留块)在dtb文件中的偏移地址,dtb文件中off_mem_rsvmap的值是0x00000028。

所以memory reservation block(内存预留块)从下图位置开始。

6.version 格式版本

version表示设备树数据结构的版本,version的值为0x0000011,对应版本为17。

7.last_comp_version最后兼容版本

last_comp_version表示向后兼容的版本,17版本向后兼容16版本,所以last_comp_version的值为16。

8.boot_cpuid_phys 我们正在启动的物理CPU ID

cpu的id值,它的值应该与设备树文件中CPU节点下的reg属性值相等。boot_cpuid_phys为0。

9.size_dt_strings字符串块的大小

size_dt_strings表示strings block(字符串块)的大小。size_dt_strings的值为0×000000058。

size_dt_strings的偏移为Ox0000024c,大小为0×00000058,0×25C+58=2a4,所以可以知道strings block(字符串块)在dtb文件中的范围。如下图所示

10.size_dt_struct 结构块的大小

size_dt_struct表示structure blockl(结构块)的大小。size_dt_struct的值为0×00000214。

off_dt_struct的偏移值是0×00000038。所以结构块在dtb文件中的范围,如下图所示:0×00000038+0×00000214=24c

2.memory reservation block(内存预留块)

如果在dts文件中使用memreserve描述保留的内存,保留内存的大小就会在这部分保存。

memreserve的使用方法:

/memreserve/  <address> <length>;

eg

//reserve memory region 0x10000000 .0x4000
/memreserve/  0x10000000 0x4000;

在内存保留块的存储格式:

struct fdt_reserve_entry {
    uint64_t address; // 地址
    uint64_t size; // 大小
};

3.structure block(结构块)

结构块描述的是设备树的结构,也就是设备树的节点。那如何表示一个节点的开始和结束呢。

使用0x00000001表示节点的开始,然后跟上节点名字(根节点的名字用0表示),然后

使用0x00000003表示一个属性的开始(每表示一个节点,都要用0x00000003表示开始),

属性的名字和值用结构体表示。

struct fdt_property {
    uint32_t tag; // 标签
    uint32_t len; // 长度
    uint32_t nameoff; // 名称偏移量
    char data[0]; // 数据
};

len表示属性值的长度,nameoff表示属性名字在字符串块中的偏移。使用0x00000002表示

节点的结束。使用表示根节点的结束。也就是整个结构块的结束。

例子中以下节点在dtb中是如何表示的呢?

/ {
    model = "this is my devicethree!";
        #address-cells = <1>;
        #size-cells = <1>;
    chosen {
        bootargs = "root=/dev/nfs rw nfsroot=192.168.1.1 console=ttyS0,115200";
    };

如下图所示:

4.strings block(字符串块)

字符串块用来存放属性的名字,比如compatible,reg等。通过分析dtb的头部,我们已经知道字符串块的位置,如model在dtb中的表示:

0x6D6F6465表示的是model的acell码,表示完一个字符串,用00结尾。


目录
相关文章
|
Docker 容器
【registry】docker 私有仓库实现https 访问
【registry】docker 私有仓库实现https 访问
2293 2
【registry】docker 私有仓库实现https 访问
|
存储 数据库 Docker
Docker Hub和镜像仓库
Docker Hub 是 Docker 公司提供的官方公共 Docker 镜像注册表,允许用户存储、分享和获取 Docker 镜像。在 Docker Hub 上,你可以找到许多官方和社区维护的 Docker 镜像,这些镜像涵盖了各种常见的应用程序和服务,如数据库、Web 服务器、应用程序框架等。
7260 0
|
Linux
【开发/调试工具】【串口工具】不同串口软件如何生成带时间戳的日志
【开发/调试工具】【串口工具】不同串口软件如何生成带时间戳的日志
3979 0
【开发/调试工具】【串口工具】不同串口软件如何生成带时间戳的日志
|
11月前
|
人工智能 测试技术 开发者
聊聊OpenAI那份Codex内部指南,以及它给我的启发
OpenAI发布《如何使用Codex》揭秘工程师真实用法:AI不仅是代码补全,更是重构助手、测试生成器和新人导师。几分钟完成数小时工作,保护开发“心流”,提升效率惊人。这才是AI编程的正确打开方式!
978 1
|
人工智能 API
通过API调用通义千问时出现DataInspectionFailed的解决办法(玄学版)
在使用qwen-plus API进行长文本翻译时,遇到了DataInspectionFailed错误,提示输入数据可能包含不当内容。尽管确认文本无敏感内容,但误判依然发生。通过将每个分段的字符数从1000降低到700,问题得以解决。建议在处理长文本时,减少每次请求的字符数以避免误判。
7135 6
|
Linux SoC
Linux设备树(DTS)介绍
**设备树(DTS)是Linux中用于描述硬件信息的文本文件,旨在减少内核与平台相关代码的耦合。DTS文件包含静态硬件配置,不支持动态变更。它被编译成DTB二进制文件,供内核在启动时解析以了解硬件布局。设备树解决了ARM体系结构代码维护的复杂性问题,通过解耦实现vendor修改的独立和共二进制目标。设备树overlay允许对配置进行增量修改,遵循特定规则,如dts覆盖dtsi,先引用后修改。调试时,可使用内置工具反编译dtb或dtbo映像为dts文本以检查内容。**
1623 7
在Linux中,什么是initrd镜像?
在Linux中,什么是initrd镜像?
|
Linux 调度
理解linux的CPU上下文切换
理解linux的CPU上下文切换
439 0
|
网络协议 物联网 开发工具
MQTT常见问题之MQTT无权连接如何解决
MQTT(Message Queuing Telemetry Transport)是一个轻量级的、基于发布/订阅模式的消息协议,广泛用于物联网(IoT)中设备间的通信。以下是MQTT使用过程中可能遇到的一些常见问题及其答案的汇总:
|
Java 容器
SpringBoot使用配置注解开启自动配置功能&整合spring-boot-configuration-processor
SpringBoot使用配置注解开启自动配置功能&整合spring-boot-configuration-processor
414 0

热门文章

最新文章