اگر حباب درختی دستگاه شما (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
...