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

شکل ۱. نمونه چیدمان بخش DTB و DTBO.
ساختارهای داده
dt_table_header فقط برای بخشبندی dtb/dtbo است؛ نمیتوانید این قالب را بعداز پایان image.gz اضافه کنید. اگر یک DTB یا DTBO دارید، باید
همچنان از این قالب استفاده کنید (و dt_entry_count در
dt_table_header برابر با ۱ است).
#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 پشتیبانی میکند.
ایجاد
برای ایجاد تصویر dtb/dtbo، از فرمان create استفاده کنید:
mkdtimg create <image_filename> (<global-option>...) \
<ftb1_filename> (<entry1_option>...) \
<ftb2_filename> (<entry2_option>...) \
...
ftbX_filename یک dt_table_entry در تصویر تولید میکند. entryX_option مقادیری است که باید به dt_table_entry اختصاص داده شود. این مقادیر میتواند هریک از موارد زیر باشد:
--id=<number|path> --rev=<number|path> --custom0=<number|path> --custom1=<number|path> --custom2=<number|path> --custom3=<number|path>
مقادیر عددی میتوانند یک رقم ۳۲ بیتی (مانند ۶۸۰۰۰) یا یک عدد هگز (مانند 0x6800) باشند. یا میتوانید مسیری را بااستفاده از قالب زیر مشخص کنید:
<full_node_path>:<property_name>
برای مثال، /board/:id. mkdtimg مقدار را از مسیر در فایل DTB یا DTBO میخواند و مقدار (۳۲ بیتی) را به دارایی نسبی در dt_table_entry اختصاص میدهد. یا میتوانید
global_option را بهعنوان گزینه پیشفرض برای همه ورودیها ارائه دهید. مقدار پیشفرض
page_size در dt_table_header برابر با ۲۰۴۸ است؛ از
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
-
dt_table_entry(board1.dtbo)idاول 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 حاشیه اضافه میکند تا اندازه .dtb/.dtbo با ۴ بایت تراز شود.
چندین ورودی جدول 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
...