Partitions DTB et DTBO

Si le blob de l'arborescence des appareils (DTB) ou le blob de l'arborescence des appareils pour la superposition (DTBO) se trouve dans une partition unique, (par exemple, les partitions dtb et dtbo), utilisez la structure de table suivante : et le format de l'en-tête:

Figure 1 : Exemple de configuration de partition DTB et DTBO.

<ph type="x-smartling-placeholder">

Structures de données

dt_table_header est uniquement pour les Partition dtb/dtbo ; vous NE POUVEZ PAS ajouter ce format après la fin de image.gz. Si vous avez un seul DTB ou DTBO, vous devez utilisent toujours ce format (et le dt_entry_count dans dt_table_header est égal à 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
};

Pour lire tous les dt_table_entry, utilisez les dt_entry_size, dt_entry_count et dt_entries_offset. Exemple :

my_read(entries_buf,
        header_addr + header->dt_entries_offset,
        header->dt_entry_size * header->dt_entry_count);

Les id, rev et custom de Les dt_table_entry sont des identifications matérielles facultatives de l'appareil. que le bootloader peut utiliser pour identifier efficacement le DTB ou DTBO à charger. Si le le bootloader nécessite des informations supplémentaires, placez-les dans DTB ou DTBO où bootloader peut le lire en analysant DTB ou DTBO (voir l'exemple de code ci-dessous).

Exemple de code

L'exemple de code suivant vérifie l'identification du matériel dans le bootloader.

  • La fonction check_dtbo() vérifie l'identification du matériel. Il vérifie d'abord les données du struct dt_table_entry (id, rev, etc.). Si ces données ne sont pas suffisantes, elles chargent dtb en mémoire et vérifie la valeur dans dtb.
  • Les valeurs de my_hw_information et soc_id sont analysées dans le nœud racine (exemple dans 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 != ...) {
        ...
      }
      ...
    }
    

Mmkdtimg

mkdtimg est un outil permettant de créer dtb image(s) sur dtbo (source : à system/libufdt dans AOSP). Compatibilité avec mkdtimg plusieurs commandes, y compris create, cfg_create et dump

create

Utilisez la commande create pour créer Image dtb/dtbo:

mkdtimg create <image_filename> (<global-option>...) \
    <ftb1_filename> (<entry1_option>...) \
    <ftb2_filename> (<entry2_option>...) \
    ...

ftbX_filename génère un dt_table_entry dans le l'image. Les entryX_option sont les valeurs à attribuer dt_table_entry Ces valeurs peuvent être l'une des suivantes:

--id=<number|path>
--rev=<number|path>
--custom0=<number|path>
--custom1=<number|path>
--custom2=<number|path>
--custom3=<number|path>

Les valeurs numériques peuvent être des chiffres de 32 bits (68 000, par exemple) ou des nombres hexadécimaux (tels que 0x6800). Vous pouvez également spécifier un chemin d'accès au format suivant:

<full_node_path>:<property_name>

(par exemple, /board/:id). mkdtimg lit la valeur du chemin dans le fichier DTB ou DTBO et affecte la valeur (32 bits) à un dans dt_table_entry. Vous pouvez également global_option est l'option par défaut pour toutes les entrées. La valeur par défaut la valeur de page_size dans dt_table_header est 2048 ; utiliser global_option --page_size=<number> pour attribuer .

Exemple :

[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 premières id (board1.dtbo) est 0x00010000 et custom[0] est 0x00000abc
  • La deuxième id est 0x00006800, et custom[0] est 0x00000abc.
  • Le troisième id est 0x00006801 et custom[0] est 0x00000123.
  • Tous les autres utilisent la valeur par défaut (0).

cfg_create

La commande cfg_create crée une image avec un fichier de configuration au format suivant:

# global options
  <global_option>
  ...
# entries
<ftb1_filename>     # comment
  <entry1_option>   # comment
  ...
<ftb2_filename>
  <entry2_option>
  ...
...

Les options global_option et entryX_option doivent commencer avec un ou plusieurs espaces (ces options sont les mêmes que les options create, sans le préfixe --). Lignes vides ou les lignes commençant par # sont ignorées.

Exemple :

[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 ne gère pas l'alignement pour .dtb/.dtbo, mais les ajoute à l'image. Lorsque vous utilisez dtc pour compiler .dts dans .dtb/.dtbo, vous devez ajouter l'option -a. Pour Par exemple, l'ajout de l'option -a 4 ajoute une marge intérieure afin que la taille de .dtb/.dtbo aligne 4 octets.

Plusieurs entrées de table de transfert de données peuvent partager un .dtb/.dtbo. Si vous utilisez le même nom de fichier pour différentes entrées, il ne stocke qu'un seul contenu dans l'image avec les mêmes dt_offset et dt_size. C'est utile lorsque vous utilisez du matériel différent avec des DT identiques.

vider

Pour dtb image(s) sur dtbo, utilisez l'dump pour imprimer les informations contenues dans l'image. Exemple :

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
...