DTB ve DTBO bölümleri

Yer paylaşımı için cihaz ağacı blob'unuz (DTB) veya cihaz ağacı blob'unuz (DTBO) benzersiz bir bölümdeyse Örneğin dtb ve dtbo bölümü için aşağıdaki tablo yapısını kullanın: ve başlık biçimi:

Şekil 1. Örnek DTB ve DTBO bölümü düzeni.

Veri yapıları

dt_table_header yalnızca dtb/dtbo bölümü; bu biçimi EKLEMEZSİNİZ image.gz bittikten sonra. Tek bir DTB veya DTBO'nuz varsa yine de bu biçimi (ve dt_entry_count dt_table_header, 1'dir).

#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 listesinin tamamını okumak için dt_entry_size, dt_entry_count ve dt_entries_offset. Örnek:

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

id, rev, custom dt_table_entry, cihazın isteğe bağlı donanım tanımlamalarıdır. Bootloader'ın yüklenecek DTB veya DTBO'yu verimli bir şekilde tanımlamak için kullanabileceği ağaç örneği. Öğe bootloader ek bilgi gerektiriyorsa, bunu DTB veya DTBO'ya yerleştirin. Buradaki bootloader, DTB veya DTBO'yu ayrıştırarak bunu okuyabilir (aşağıdaki örnek koda bakın).

Örnek kod

Aşağıdaki örnek kod, bootloader'da donanım tanımlamasını kontrol eder.

  • check_dtbo() işlevi, donanım kimliğini kontrol eder. İlk olarak struct dt_table_entry (id, rev vb.). Bu veri yeterli değilse dtb yüklenir belleğe ekler ve dtb içindeki değeri kontrol eder.
  • my_hw_information ve soc_id değerleri özellikleri kök düğümde ayrıştırılır (my_dtbo_1.dts içinden örnek).
    [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, kullanıcıların dtb/dtbo resim (kaynak kodu (AOSP'deki system/libufdt) mkdtimg destekler create, cfg_create ve çeşitli komutlar dahil dump.

oluştur

Yeni bir komut oluşturmak için create komutunu kullanın dtb/dtbo resim:

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

ftbX_filename, dt_table_entry görüntüsüdür. entryX_option öğeleri, atanacak değerlerdir dt_table_entry. Bu değerler aşağıdakilerden herhangi biri olabilir:

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

Sayı değerleri, 32 bitlik bir rakam (ör. 68.000) veya onaltılık bir sayı (ör. 0x6800). Alternatif olarak, şu biçimi kullanarak da bir yol belirtebilirsiniz:

<full_node_path>:<property_name>

Örneğin, /board/:id. mkdtimg, değeri okur dosya yolunu DTB ya da DTBO dosyasındaki yoldan alır ve değeri (32 bit) dt_table_entry konumundaki mülk. Alternatif olarak, Tüm girişler için varsayılan seçenek olarak global_option. Varsayılan dt_table_header içindeki page_size değeri 2048'dir; kullan global_option --page_size=<number> ve farklı bir değer.

Örnek:

[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
  • İlk dt_table_entry (board1.dtbo) id 0x00010000, custom[0] ise 0x00000abc.
  • İkinci id 0x00006800 ve custom[0] 0x00000abc.
  • Üçüncü id: 0x00006801 ve custom[0] 0x00000123.
  • Diğer tüm mülkler varsayılan değeri (0) kullanır.

cfg_oluşturma

cfg_create komutu, şu biçimdedir:

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

global_option ve entryX_option seçeneklerinin başlaması gerekiyor bir veya daha fazla boşluk karakteri içeren bir sayı (bu seçenekler -- ön eki olmadan create seçenekleri). Boş satırlar veya # ile başlayan satırlar yoksayılır.

Örnek:

[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, hizalama işlemini yapmaz. .dtb/.dtbo dosyaları, bunun yerine bunları resme ekler. .dts öğesini derlemek için dtc kullandığınızda .dtb/.dtbo, -a seçeneğini eklemelisiniz. Örneğin, Örneğin -a 4 seçeneği eklendiğinde, .dtb/.dtbo, 4 bayt olarak hizalanır.

Birçok DT tablosu girişi bir .dtb/.dtbo öğesini paylaşabilir. Eğer Farklı girişler için aynı dosya adını kullanırsanız, bu dosya şurada yalnızca bir içeriği resmi, aynı dt_offset ve dt_size değerine sahip. Bu aynı DT'lere sahip farklı donanımlar kullanıldığında kullanışlıdır.

döküm

dtb/dtbo resim için dump özelliğini kullanın komutunu kullanın. Örnek:

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