Befindet sich Ihr Gerätebaum-BLOB (Device Tree Blob, Device Tree Blob) oder „Device Tree Blob for Overlay“ (DTBO) in einer eindeutigen Partition,
Die Partition dtb
und dtbo
hat beispielsweise die folgende Tabellenstruktur:
und Headerformat:
Abbildung 1: Beispiel für ein DTB- und DTBO-Partitionslayout.
<ph type="x-smartling-placeholder">Datenstrukturen
dt_table_header
gilt nur für den
Partition dtb
/dtbo
; Sie KÖNNEN dieses Format NICHT anhängen
nach dem Ende von image.gz
. Bei einem einzelnen DTB oder DTBO
weiterhin dieses Format verwenden (und die dt_entry_count
in
dt_table_header
ist 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 };
Um alle dt_table_entry
zu lesen, verwenden Sie dt_entry_size
,
dt_entry_count
und dt_entries_offset
. Beispiel:
my_read(entries_buf, header_addr + header->dt_entries_offset, header->dt_entry_size * header->dt_entry_count);
id
, rev
und custom
in
dt_table_entry
sind optionale Hardware-Identifikationen des Geräts
Baum, anhand dessen der Bootloader den zu ladenden DTB oder DTBO effizient identifizieren kann. Wenn die
Bootloader benötigt zusätzliche Informationen, speichere
die DTB oder DTBO
Bootloader kann sie durch Parsen von DTB oder DTBO lesen (siehe Beispielcode unten).
Beispielcode
Der folgende Beispielcode prüft die Hardware-Identifizierung im Bootloader.
- Die Funktion
check_dtbo()
prüft die Hardwareidentifikation. Zuerst werden die Daten in der Strukturdt_table_entry
(id
,rev
usw.). Wenn diese Daten nicht ausreichen, werdendtb
geladen. Daten in den Arbeitsspeicher und prüft den Wert indtb
. - Die Werte von
my_hw_information
undsoc_id
Properties werden im Stammknoten geparst (Beispiel inmy_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
ist ein Tool zum Erstellen
dtb
/dtbo
Bildern
(Quelle
Code unter system/libufdt
in AOSP). mkdtimg
unterstützt
verschiedene Befehle, darunter create
, cfg_create
und
dump
.
create
Verwenden Sie den Befehl create
, um eine
dtb
/dtbo
Bild:
mkdtimg create <image_filename> (<global-option>...) \
<ftb1_filename> (<entry1_option>...) \
<ftb2_filename> (<entry2_option>...) \
...
ftbX_filename
generiert ein dt_table_entry
im
Bild. entryX_option
-Werte sind die Werte, die
dt_table_entry
. Folgende Werte sind möglich:
--id=<number|path> --rev=<number|path> --custom0=<number|path> --custom1=<number|path> --custom2=<number|path> --custom3=<number|path>
Zahlenwerte können eine 32-Bit-Ziffer (z. B. 68.000) oder eine Hexadezimalzahl (z. B. 0x6800). Alternativ können Sie einen Pfad im folgenden Format angeben:
<full_node_path>:<property_name>
Beispiel: /board/:id
. mkdtimg
liest den Wert
aus dem Pfad in der DTB- oder DTBO-Datei und weist den Wert (32-Bit) einem relativen
in dt_table_entry
. Alternativ können Sie auch eine
global_option
als Standardoption für alle Einträge. Standardeinstellung
Wert von page_size
in dt_table_header
ist 2048; nutzen
global_option --page_size=<number>
, um eine andere
Wert.
Beispiel:
[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
- Erste
dt_table_entry
(board1.dtbo
)id
ist0x00010000
undcustom[0]
ist0x00000abc
- Der zweite
id
ist0x00006800
undcustom[0]
ist0x00000abc
. - Der dritte
id
ist0x00006801
undcustom[0]
ist0x00000123
. - Alle anderen verwenden den Standardwert (
0
).
cfg_create
Der Befehl cfg_create
erstellt ein Image mit einer Konfigurationsdatei in
im folgenden Format:
# global options <global_option> ... # entries <ftb1_filename> # comment <entry1_option> # comment ... <ftb2_filename> <entry2_option> ... ...
Optionen global_option
und entryX_option
müssen beginnen
mit einem oder mehreren Leerzeichen (diese Optionen entsprechen der
create
-Optionen ohne das Präfix --
). Leere Zeilen oder
Zeilen, die mit #
beginnen, werden ignoriert.
Beispiel:
[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
übernimmt die Ausrichtung nicht für
.dtb
/.dtbo
-Dateien an, sondern hängt sie an das Bild an.
Wenn Sie dtc
verwenden, um .dts
zu kompilieren,
.dtb
/.dtbo
, du musst die Option -a
hinzufügen. Für
Durch Hinzufügen der Option -a 4
wird ein Abstand
hinzugefügt, sodass die Größe der
.dtb
/.dtbo
entspricht 4 Byte.
Mehrere DT-Tabelleneinträge können .dtb
/.dtbo
gemeinsam nutzen. Wenn
Sie denselben Dateinamen für verschiedene Einträge verwenden, wird nur ein Inhalt in
das Bild mit denselben dt_offset
und dt_size
. Dies ist
nützlich bei Verwendung unterschiedlicher Hardware mit identischen DTs.
auslagern
Für dtb
/dtbo
Bilder dump
verwenden
um die Informationen im Bild auszugeben. Beispiel:
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
...