设备树dtb文件的格式分析

36 篇文章 3 订阅
6 篇文章 1 订阅

设备树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结尾。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

苦梨甜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值