Partisi DTB dan DTBO

Jika blob hierarki perangkat (DTB) atau blob hierarki perangkat untuk overlay (DTBO) berada di partisi unik, misalnya, partisi dtb dan dtbo, gunakan struktur tabel berikut dan format header:

Gambar 1. Contoh tata letak partisi DTB dan DTBO.

Struktur data

dt_table_header hanya untuk Partisi dtb/dtbo; Anda TIDAK DAPAT menambahkan format ini setelah akhir image.gz. Jika Anda memiliki satu DTB atau DTBO, Anda harus masih menggunakan format ini (dan dt_entry_count dalam dt_table_header adalah 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
};

Untuk membaca semua dt_table_entry, gunakan dt_entry_size, dt_entry_count, dan dt_entries_offset. Contoh:

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

id, rev, custom di dt_table_entry adalah identifikasi hardware opsional dari perangkat yang dapat digunakan {i>bootloader<i} untuk mengidentifikasi DTB atau DTBO yang akan dimuat secara efisien. Jika {i>bootloader<i} membutuhkan informasi tambahan, masukkan ke dalam DTB atau DTBO di mana bootloader dapat membacanya dengan menguraikan DTB atau DTBO (lihat kode contoh di bawah).

Kode contoh

Kode contoh berikut memeriksa identifikasi hardware di bootloader.

  • Fungsi check_dtbo() memeriksa identifikasi hardware. Kode ini akan memeriksa data terlebih dahulu di struct dt_table_entry (id, rev, dll.). Jika data ini tidak cukup, akan dimuat dtb data ke dalam memori dan memeriksa nilainya di dtb.
  • Nilai my_hw_information dan soc_id properti diuraikan dalam node root (contoh di 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 != ...) {
        ...
      }
      ...
    }
    

{i>mkdtimg<i}

mkdtimg adalah alat untuk membuat dtb/dtbo gambar (sumber kode di system/libufdt di AOSP). mkdtimg mendukung beberapa perintah, termasuk create, cfg_create, dan dump.

create

Gunakan perintah create untuk membuat Gambar dtb/dtbo:

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

ftbX_filename menghasilkan dt_table_entry di gambar. entryX_option adalah nilai yang akan ditetapkan dt_table_entry. Nilai ini dapat berupa salah satu dari berikut ini:

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

Nilai angka dapat berupa digit 32-bit (seperti 68000) atau angka heksadesimal (seperti 0x6800). Atau, Anda dapat menentukan jalur menggunakan format:

<full_node_path>:<property_name>

Misalnya, /board/:id. mkdtimg membaca nilai dari jalur dalam file DTB atau DTBO dan menetapkan nilai (32-bit) ke relatif di dt_table_entry. Atau, Anda dapat memberikan global_option sebagai opsi default untuk semua entri. Default nilai page_size di dt_table_header adalah 2048; penggunaan global_option --page_size=<number> untuk menetapkan dengan sejumlah nilai.

Contoh:

[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 pertama adalah 0x00010000 dan custom[0] adalah 0x00000abc.
  • id kedua adalah 0x00006800 dan custom[0] adalah 0x00000abc.
  • id ketiga adalah 0x00006801 dan custom[0] adalah 0x00000123.
  • Yang lainnya menggunakan nilai default (0).

{i>cfg_create<i}

Perintah cfg_create membuat image dengan file konfigurasi di dalam format berikut:

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

Opsi global_option dan entryX_option harus dimulai dengan satu karakter spasi atau lebih (opsi ini sama dengan opsi create, tanpa awalan --). Baris kosong atau baris yang dimulai dengan # akan diabaikan.

Contoh:

[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 tidak menangani penyelarasan untuk .dtb/.dtbo, tetapi menambahkannya ke gambar. Saat Anda menggunakan dtc untuk mengompilasi .dts guna .dtb/.dtbo, Anda harus menambahkan opsi -a. Sebagai Misalnya, menambahkan opsi -a 4 akan menambahkan padding sehingga ukuran .dtb/.dtbo selaras dengan 4 byte.

Beberapa entri tabel DT dapat membagikan .dtb/.dtbo. Jika Anda menggunakan nama file yang sama untuk entri yang berbeda, sistem ini hanya menyimpan satu konten gambar dengan dt_offset dan dt_size yang sama. Ini adalah berguna saat menggunakan perangkat keras yang berbeda dengan DT yang identik.

{i>dump<i}

Untuk dtb/dtbo gambar, gunakan dump untuk mencetak informasi dalam gambar. Contoh:

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