DTB এবং DTBO পার্টিশন

যদি আপনার ডিভাইস ট্রি ব্লব (DTB) বা ডিভাইস ট্রি ব্লব ফর ওভারলে (DTBO) একটি অনন্য পার্টিশনে থাকে, উদাহরণস্বরূপ, dtb এবং dtbo পার্টিশন, নিম্নলিখিত টেবিলের গঠন এবং হেডার বিন্যাসটি ব্যবহার করুন:

চিত্র 1. উদাহরণ DTB এবং DTBO পার্টিশন লেআউট।

ডেটা স্ট্রাকচার

dt_table_header শুধুমাত্র dtb / dtbo পার্টিশনের জন্য; আপনি image.gz শেষ হওয়ার পরে এই বিন্যাসটি যুক্ত করতে পারবেন না। আপনার যদি একটি একক DTB বা DTBO থাকে, তবে আপনাকে অবশ্যই এই ফর্ম্যাটটি ব্যবহার করতে হবে (এবং dt_table_headerdt_entry_count হল 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);

dt_table_entryid , rev , custom হল ডিভাইস ট্রির ঐচ্ছিক হার্ডওয়্যার শনাক্তকরণ যা বুটলোডার লোড করার জন্য DTB বা DTBO কে দক্ষতার সাথে সনাক্ত করতে ব্যবহার করতে পারে। বুটলোডারের অতিরিক্ত তথ্যের প্রয়োজন হলে, এটি DTB বা DTBO-তে রাখুন যেখানে বুটলোডার DTB বা DTBO পার্স করে এটি পড়তে পারে (নীচের নমুনা কোডটি দেখুন)।

নমুনা কোড

নিম্নলিখিত নমুনা কোড বুটলোডারে হার্ডওয়্যার সনাক্তকরণ পরীক্ষা করে।

  • check_dtbo() ফাংশন হার্ডওয়্যার সনাক্তকরণ পরীক্ষা করে। এটি প্রথমে struct 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 ইমেজ তৈরি করার জন্য একটি টুল ( AOSP-এ system/libufdt সোর্স কোড )। mkdtimg create , cfg_create , এবং dump সহ বিভিন্ন কমান্ড সমর্থন করে।

তৈরি

একটি dtb / dtbo ইমেজ তৈরি করতে create কমান্ডটি ব্যবহার করুন:

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/:idmkdtimg DTB বা DTBO ফাইলের পাথ থেকে মানটি পড়ে এবং dt_table_entry এ একটি আপেক্ষিক সম্পত্তিতে মান (32-বিট) বরাদ্দ করে। বিকল্পভাবে, আপনি সমস্ত এন্ট্রির জন্য একটি ডিফল্ট বিকল্প হিসাবে একটি global_option দিতে পারেন। dt_table_headerpage_size এর ডিফল্ট মান হল 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
  • প্রথম dt_table_entry ( board1.dtbo ) id হল 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 ফাইলগুলির জন্য সারিবদ্ধকরণ পরিচালনা করে না বরং সেগুলিকে চিত্রের সাথে যুক্ত করে। আপনি যখন .dts থেকে .dtb / .dtbo কম্পাইল করতে dtc ব্যবহার করেন, তখন আপনাকে অবশ্যই বিকল্প -a যোগ করতে হবে। উদাহরণস্বরূপ, -a 4 বিকল্পটি যোগ করলে প্যাডিং যুক্ত হয় যাতে .dtb / .dtbo এর আকার 4 বাইটে সারিবদ্ধ হয়।

বেশ কয়েকটি ডিটি টেবিল এন্ট্রি একটি .dtb / .dtbo শেয়ার করতে পারে। আপনি যদি বিভিন্ন এন্ট্রির জন্য একই ফাইলের নাম ব্যবহার করেন, তাহলে এটি একই dt_offset এবং dt_size সহ ছবিতে শুধুমাত্র একটি বিষয়বস্তু সঞ্চয় করে। অভিন্ন ডিটি সহ বিভিন্ন হার্ডওয়্যার ব্যবহার করার সময় এটি কার্যকর।

ডাম্প

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