当前位置:   article > 正文

Android DT/DTO镜像简介_mkdtboimg.py

mkdtboimg.py

下图引自:https://source.android.com/devices/architecture/dto/partitions
本文中所述工具和源码详见Google代码仓:
git clone https://android.googlesource.com/platform/system/libufdt
在这里插入图片描述
dt或者dto镜像在这里Google把它笼统地称作dtbo镜像,他们的格式是一样的,都是把多个dtc编译出来的dtb二进制或者dto二进制打包到一个image,在image的结尾加一个avb的校验签名或者各个厂商自定义的镜像签名。
多个硬件设备可能配置都不一样,寄存器或者内存大小的配置等。每个硬件设备对应一个dtb和dto,把多个dtb或者dto按照图示的格式打包成对应的dt.img和dto.img,这样软件可以做到共镜像,方便了厂商对产品的维护工作。
每个硬件设备怎么识别到对应自己的dtb和dto呢?这里就需要依赖dt_table_entry中的id、rev、custom这几个字段了,它作用是硬件标识。这样bootloader就可以根据硬件设备获取的标识加载匹配的dtb和dto了。
例如:单板配置一和二

jun@ubuntu:~/dtbo/libufdt/utils/tests/data$ cat board1v1.dts
/dts-v1/;
/plugin/;

/ {
  compatible = "board_manufacturer,board_model";
  board_id = <0x00010000>;
  board_rev = <0x00010000>;
  /* optional, the soc used by the board */
  soc_id = <0x00020000>;

  deviceB:deviceB {
  };
};

&deviceB {
  value = <0x1>;
  status = "okay";
};
jun@ubuntu:~/dtbo/libufdt/utils/tests/data$ cat board2v1.dts
/dts-v1/;
/plugin/;

/ {
  compatible = "board_manufacturer,board_model";
  board_id = <0x00020000>;
  board_rev = <0x00010000>;
  /* optional, the soc used by the board */
  soc_id = <0x00010000>;

  deviceA: deviceA {
  };
};

&deviceA {
  value = <0x1>;
  status = "okay";
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

安装dts编译器:

sudo apt install device-tree-compiler
jun@ubuntu:~/dtbo/libufdt/utils/tests/data$ dtc --version
Version: DTC 1.4.5
  • 1
  • 2
  • 3

编译dts到dtb二进制格式:

dtc -O dtb board1v1.dts -o board1v1.dtb
dtc -O dtb board2v1.dts -o board2v1.dtb
  • 1
  • 2

使用mkdtboimg.py工具制作生成dt.img
注意:version参数没有或者是0,代表打包前不对dtb进行压缩处理,如果version参数为1,并且配合flags参数可设置dtb压缩格式。
flags为0,不压缩dtb
flags为1,zlib压缩dtb
flags为2,gzip压缩dtb

jun@ubuntu:~/dtbo/libufdt/utils/tests/data$ ../../src/mkdtboimg.py create dt.img --page_size=4096 --flags=2 --version=1 board1v1.dtb --id=0x10000 board2v1.dtb --id=0x20000
jun@ubuntu:~/dtbo/libufdt/utils/tests/data$ ../../src/mkdtboimg.py dump dt.img
dt_table_header:
               magic = d7b7ab1e
          total_size = 429
         header_size = 32
       dt_entry_size = 32
      dt_entry_count = 2
   dt_entries_offset = 32
           page_size = 4096
             version = 1
dt_table_entry[0]:
             dt_size = 166
           dt_offset = 96
                  id = 00010000
                 rev = 00000000
           custom[0] = 00000002
           custom[1] = 00000000
           custom[2] = 00000000
           custom[3] = 00000000
dt_table_entry[1]:
             dt_size = 167
           dt_offset = 262
                  id = 00020000
                 rev = 00000000
           custom[0] = 00000002
           custom[1] = 00000000
           custom[2] = 00000000
           custom[3] = 00000000
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

dtbo镜像详细的数据结构定义:

#define DT_TABLE_MAGIC 0xd7b7ab1e
#define DT_TABLE_DEFAULT_PAGE_SIZE 2048
#define DT_TABLE_DEFAULT_VERSION 0

struct dt_table_header {
  uint32_t magic;             /* DT_TABLE_MAGIC */
  uint32_t total_size;        /* includes dt_table_header + all dt_table_entry
                                 and all dtb/dtbo */
  uint32_t header_size;       /* sizeof(dt_table_header) */

  uint32_t dt_entry_size;     /* sizeof(dt_table_entry) */
  uint32_t dt_entry_count;    /* number of dt_table_entry */
  uint32_t dt_entries_offset; /* offset to the first dt_table_entry
                                 from head of dt_table_header.
                                 The value will be equal to header_size if
                                 no padding is appended */

  uint32_t page_size;         /* flash page size we assume */
  uint32_t version;           /* DTBO image version, the current version is 0.
                                 The version will be incremented when the dt_table_header
                                 struct is updated. */
};
// 下面定义的是dtb或dto支持的压缩格式,mkdtboimg.py命令行version必须为1,flags可设0~2
enum dt_compression_info {
    NO_COMPRESSION,     // mkdtboimg.py --version=1 --flags=0
    ZLIB_COMPRESSION,   // mkdtboimg.py --version=1 --flags=1
    GZIP_COMPRESSION    // mkdtboimg.py --version=1 --flags=2
};
// 下面这个结构体对应的是mkdtboimg.py脚本命令行参数version是0或默认的情况
struct dt_table_entry {
  uint32_t dt_size;
  uint32_t dt_offset;         /* offset from head of dt_table_header */

  uint32_t id;                /* optional, must be zero if unused */
  uint32_t rev;               /* optional, must be zero if unused */
  uint32_t custom[4];         /* optional, must be zero if unused */
};
// 下面这个结构体对应的是mkdtboimg.py脚本命令行参数version是1的情况
struct dt_table_entry_v1 {
  uint32_t dt_size;
  uint32_t dt_offset;         /* offset from head of dt_table_header */

  uint32_t id;                /* optional, must be zero if unused */
  uint32_t rev;               /* optional, must be zero if unused */
  uint32_t flags;             /* For version 1 of dt_table_header, the 4 least significant bits
                                 of 'flags' will be used indicate the compression
                                 format of the DT entry as per the enum 'dt_compression_info' */
  uint32_t custom[3];         /* optional, must be zero if unused */
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49

bootloader中查找硬件设备对于的dtb或者dto示例代码:

#include <stdlib.h>
#include <stdio.h>
#include "../../src/dt_table.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <endian.h>

void *read_dtbo(char *ptn)
{
	int ret;
	char *dtbo;
	struct stat buf = {0};

	ret = stat(ptn, &buf);
	if (ret != 0) {
		printf("stat err\n");
		return NULL;
	}

	dtbo = (char *)malloc(buf.st_size);
	ret = open(ptn, O_RDONLY);
	if (ret < 0) {
		printf("open fail\n");
		return NULL;
	}
	ret = read(ret, dtbo, buf.st_size);
	if (ret != buf.st_size) {
		printf("read err\n");
		return NULL;
	}
	return dtbo;
}


unsigned int get_board_id(void)
{
	return 0x20000;
}

void *load_dtbo(void)
{
	char *dtbo;
	struct dt_table_header *dtbo_head;
	unsigned int board_id;
	struct dt_table_entry_v1 *dtbo_entry;

	dtbo = read_dtbo("dt.img");
	if (!dtbo) {
		printf("read_dtbo err!\n");
		return NULL;
	}

	dtbo_head = (struct dt_table_header *)dtbo;
	printf("magic %x\n", be32toh(dtbo_head->magic));
	if (be32toh(dtbo_head->magic) != DT_TABLE_MAGIC) {
		printf("Magic not match!\n");
		return NULL;
	}

	board_id = get_board_id();
	for (dtbo_entry = (struct dt_table_entry_v1 *)(dtbo + be32toh(dtbo_head->dt_entries_offset));
	     (char *)dtbo_entry < dtbo + be32toh(dtbo_head->dt_entries_offset) +
	     be32toh(dtbo_head->dt_entry_size) * be32toh(dtbo_head->dt_entry_count);
	     ++dtbo_entry) {
		if (be32toh(dtbo_entry->id) == board_id) {
			printf("dtbo_entry info dt_size %x\n",   be32toh(dtbo_entry->dt_size));
			printf("dtbo_entry info dt_offset %x\n", be32toh(dtbo_entry->dt_offset));
			printf("dtbo_entry info id %x\n",        be32toh(dtbo_entry->id));
			printf("dtbo_entry info rev %x\n",       be32toh(dtbo_entry->rev));
			break;
		}
	}
	return dtbo_entry;
}

void main()
{
	load_dtbo();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Guff_9hys/article/detail/1005082
推荐阅读
相关标签
  

闽ICP备14008679号