اگر حباب درختی دستگاه شما (DTB) یا حباب درخت دستگاه برای پوشش (DTBO) در یک پارتیشن منحصر به فرد است، به عنوان مثال، پارتیشن dtb و dtbo ، از ساختار جدول و فرمت هدر زیر استفاده کنید:

شکل 1. نمونه طرح پارتیشن DTB و DTBO.
ساختارهای داده
dt_table_header فقط برای پارتیشن dtb / dtbo است. شما نمی توانید این قالب را بعد از پایان image.gz اضافه کنید. اگر یک DTB یا DTBO دارید، همچنان باید از این قالب استفاده کنید (و dt_entry_count در dt_table_header 1 است).
#define DT_TABLE_MAGIC 0xd7b7ab1e
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
uint32_t page_size; // flash page size we assume
uint32_t version; // DTBO image version, the current version is 0.
// The version is incremented when the
// dt_table_header struct is updated.
};
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
}; برای خواندن تمام dt_table_entry ، dt_entry_size ، dt_entry_count و dt_entries_offset استفاده کنید. مثال:
my_read(entries_buf, header_addr + header->dt_entries_offset, header->dt_entry_size * header->dt_entry_count);
id , rev , custom در dt_table_entry شناسه های سخت افزاری اختیاری درخت دستگاه هستند که بوت لودر می تواند برای شناسایی موثر DTB یا DTBO برای بارگذاری استفاده کند. اگر بوت لودر به اطلاعات بیشتری نیاز دارد، آن را در DTB یا DTBO قرار دهید تا بوت لودر بتواند با تجزیه DTB یا DTBO آن را بخواند (نمونه کد زیر را ببینید).
کد نمونه
کد نمونه زیر شناسایی سخت افزار را در بوت لودر بررسی می کند.
- تابع
check_dtbo()شناسایی سخت افزار را بررسی می کند. ابتدا داده ها را در ساختارdt_table_entry(id،rev، و غیره) بررسی می کند. اگر این داده ها کافی نباشد، داده هایdtbرا در حافظه بارگیری می کند و مقدارdtbرا بررسی می کند. - مقادیر
my_hw_informationو ویژگیهایsoc_idدر گره ریشه تجزیه میشوند (به عنوان مثال درmy_dtbo_1.dts).[my_dtbo_1.dts] /dts-v1/; /plugin/; / { /* As DTS design, these properties only for loader, won't overlay */ compatible = "board_manufacturer,board_model"; /* These properties are examples */ board_id = <0x00010000>; board_rev = <0x00010001>; another_hw_information = "some_data"; soc_id = <0x68000000>; ... }; &device@0 { value = <0x1>; status = "okay"; }; [my_bootloader.c] int check_dtbo(const dt_table_entry *entry, uint32_t header_addr) { ... if (entry->id != ... || entry->rev != ...) { ... } ... void * fdt_buf = my_load_dtb(header_addr + entry->dt_offset, entry->dt_size); int root_node_off = fdt_path_offset(fdt_buf, "/"); ... const char *my_hw_information = (const char *)fdt_getprop(fdt_buf, root_node_off, "my_hw_information", NULL); if (my_hw_information != NULL && strcmp(my_hw_information, ...) != 0) { ... } const fdt32_t *soc_id = fdt_getprop(fdt_buf, root_node_off, "soc_id", NULL); if (soc_id != NULL && *soc_id != ...) { ... } ... }
mkdtimg
mkdtimg ابزاری برای ایجاد تصاویر dtb / dtbo است ( کد منبع در system/libufdt در AOSP). mkdtimg از چندین دستور از جمله create ، cfg_create و dump پشتیبانی می کند.
ایجاد کنید
از دستور create برای ایجاد تصویر dtb / dtbo استفاده کنید:
mkdtimg create <image_filename> (<global-option>...) \
<ftb1_filename> (<entry1_option>...) \
<ftb2_filename> (<entry2_option>...) \
...
ftbX_filename یک dt_table_entry در تصویر ایجاد می کند. entryX_option s مقادیری هستند که باید به dt_table_entry نسبت داده شوند. این مقادیر می تواند یکی از موارد زیر باشد:
--id=<number|path> --rev=<number|path> --custom0=<number|path> --custom1=<number|path> --custom2=<number|path> --custom3=<number|path>
مقادیر اعداد می توانند یک رقم 32 بیتی (مانند 68000) یا یک عدد هگز (مانند 0x6800) باشند. همچنین می توانید مسیری را با استفاده از فرمت مشخص کنید:
<full_node_path>:<property_name>
برای مثال /board/:id . mkdtimg مقدار را از مسیر موجود در فایل DTB یا DTBO می خواند و مقدار (32 بیتی) را به یک ویژگی نسبی در dt_table_entry اختصاص می دهد. همچنین، میتوانید یک global_option به عنوان گزینه پیشفرض برای همه ورودیها بدهید. مقدار پیش فرض page_size در dt_table_header 2048 است. از global_option --page_size=<number> برای اختصاص یک مقدار متفاوت استفاده کنید.
مثال:
[board1.dts]
/dts-v1/;
/plugin/;
/ {
compatible = "board_manufacturer,board_model";
board_id = <0x00010000>;
board_rev = <0x00010001>;
another_hw_information = "some_data";
...
};
&device@0 {
value = <0x1>;
status = "okay";
};
mkdtimg create dtbo.img --id=/:board_id --custom0=0xabc \
board1.dtbo \
board2.dtbo --id=0x6800 \
board3.dtbo --id=0x6801 --custom0=0x123
-
idاولdt_table_entry(board1.dtbo)0x00010000وcustom[0]0x00000abcاست. -
idدوم0x00006800وcustom[0]0x00000abcاست. -
idسوم0x00006801وcustom[0]0x00000123است. - بقیه از مقدار پیش فرض (
0) استفاده می کنند.
cfg_create
دستور cfg_create یک تصویر با یک فایل کانفیگ با فرمت زیر ایجاد می کند:
# global options <global_option> ... # entries <ftb1_filename> # comment <entry1_option> # comment ... <ftb2_filename> <entry2_option> ... ...
گزینه های global_option و entryX_option باید با یک یا چند کاراکتر فاصله شروع شوند (این گزینه ها مانند گزینه های create بدون پیشوند -- هستند). خطوط خالی یا خطوطی که با # شروع می شوند نادیده گرفته می شوند.
مثال:
[dtboimg.cfg]
# global options
id=/:board_id
rev=/:board_rev
custom0=0xabc
board1.dtbo
board2.dtbo
id=0x6800 # override the value of id in global options
board2.dtbo
id=0x6801 # override the value of id in global options
custom0=0x123 # override the value of custom0 in global options
mkdtimg cfg_create dtbo.img dtboimg.cfg
mkdtimg تراز فایلهای .dtb / .dtbo را مدیریت نمیکند، بلکه آنها را به تصویر اضافه میکند. هنگامی که از dtc برای کامپایل .dts به .dtb / .dtbo استفاده می کنید، باید گزینه -a اضافه کنید. به عنوان مثال، با افزودن گزینه -a 4 ، padding اضافه می شود تا اندازه .dtb / .dtbo به 4 بایت تراز شود.
چندین ورودی جدول DT می توانند یک .dtb / .dtbo را به اشتراک بگذارند. اگر از یک نام فایل برای ورودی های مختلف استفاده می کنید، فقط یک محتوا را در تصویر با همان dt_offset و dt_size ذخیره می کند. این هنگام استفاده از سخت افزارهای مختلف با DTهای یکسان مفید است.
تخلیه
برای تصاویر dtb / dtbo ، از دستور dump برای چاپ اطلاعات موجود در تصویر استفاده کنید. مثال:
mkdtimg dump dtbo.img
dt_table_header:
magic = d7b7ab1e
total_size = 1300
header_size = 32
dt_entry_size = 32
dt_entry_count = 3
dt_entries_offset = 32
page_size = 2048
version = 0
dt_table_entry[0]:
dt_size = 380
dt_offset = 128
id = 00010000
rev = 00010001
custom[0] = 00000abc
custom[1] = 00000000
custom[2] = 00000000
custom[3] = 00000000
(FDT)size = 380
(FDT)compatible = board_manufacturer,board_model
...