DTOs অপ্টিমাইজ করা

এই পৃষ্ঠাটি আপনার ডিটিও বাস্তবায়নে আপনি যে অপ্টিমাইজেশনগুলি করতে পারেন তা নিয়ে আলোচনা করে, রুট নোডকে ওভারলে করার বিরুদ্ধে বিধিনিষেধগুলি বর্ণনা করে এবং ডিটিবিও ছবিতে সংকুচিত ওভারলেগুলি কীভাবে কনফিগার করতে হয় তার বিশদ বিবরণ দেয়৷ এটি নমুনা বাস্তবায়ন নির্দেশাবলী এবং কোড প্রদান করে।

কার্নেল কমান্ড লাইন

ডিভাইস ট্রিতে মূল কার্নেল কমান্ড লাইনটি chosen/bootargs নোডে অবস্থিত। বুটলোডারকে অবশ্যই এই অবস্থানটি কার্নেল কমান্ড লাইনের অন্যান্য উত্সগুলির সাথে সংযুক্ত করতে হবে:

/dts-v1/;

/ {
  chosen: chosen {
    bootargs = "...";
  };
};

DTO প্রধান DT এবং ওভারলে DT থেকে মান সংযুক্ত করতে পারে না , তাই আপনাকে অবশ্যই chosen/bootargs প্রধান ডিটির কার্নেল কমান্ড লাইন এবং chosen/bootargs_ext এ ওভারলে ডিটির কার্নেল কমান্ড লাইন রাখতে হবে। বুটলোডার তারপর এই অবস্থানগুলিকে সংযুক্ত করতে পারে এবং ফলাফলটি কার্নেলে পাঠাতে পারে।

main.dts overlay.dts
/dts-v1/;

/ {
  chosen: chosen {
    bootargs = "...";
  };
};
/dts-v1/;
/plugin/;

&chosen {
  bootargs_ext = "...";
};

libufdt

সর্বশেষ libfdt DTO সমর্থন করে, DTO (AOSP source at platform/system/libufdt ) বাস্তবায়নের জন্য libufdt ব্যবহার করার সুপারিশ করা হয়। libufdt ফ্ল্যাটেন্ড ডিভাইস ট্রি (FDT) থেকে একটি বাস্তব ট্রি স্ট্রাকচার (আন-ফ্ল্যাটেনড ডিভাইস ট্রি, বা ufdt ) তৈরি করে, তাই এটি O(N 2 ) থেকে O(N) তে দুটি .dtb ফাইল একত্রিত করার উন্নতি করতে পারে, যেখানে N গাছে নোডের সংখ্যা।

কর্মক্ষমতা পরীক্ষা

গুগলের অভ্যন্তরীণ পরীক্ষায়, 2405 .dtb এবং 283 .dtbo DT নোডগুলিতে libufdt ব্যবহার করলে সংকলনের পরে ফাইলের আকার 70,618 এবং 8,566 বাইট হয়। FreeBSD (124 ms রানটাইম) থেকে পোর্ট করা একটি DTO বাস্তবায়নের সাথে তুলনা করে, libufdt DTO রানটাইম হল 10 ms।

libufdt এবং libfdt তুলনা করা Pixel ডিভাইসের জন্য পারফরম্যান্স টেস্টিং। বেস নোডের প্রভাবের সংখ্যা অনুরূপ, তবে নিম্নলিখিত পার্থক্যগুলি অন্তর্ভুক্ত করে:

  • 500 ওভারলে (সংযোজন বা ওভাররাইড) অপারেশনে 6x থেকে 8x সময়ের পার্থক্য রয়েছে
  • 1000 ওভারলে (সংযোজন বা ওভাররাইড) অপারেশনে 8x থেকে 10x সময়ের পার্থক্য রয়েছে

X এ সেট করা সংখ্যা সংযোজন সহ উদাহরণ:

চিত্র 1. সংযোজন সংখ্যা হল X

ওভাররাইডিং গণনা X এ সেট করা উদাহরণ সহ:

চিত্র 2. ওভাররাইডিং সংখ্যা হল X

libufdt কিছু libfdt API এবং ডেটা স্ট্রাকচারের সাথে তৈরি করা হয়েছে। libufdt ব্যবহার করার সময়, আপনাকে অবশ্যই libfdt অন্তর্ভুক্ত এবং লিঙ্ক করতে হবে (তবে, আপনার কোডে আপনি DTB বা DTBO পরিচালনা করতে libfdt API ব্যবহার করতে পারেন)।

libufdt DTO API

libufdt এ DTO-এর প্রধান API নিম্নরূপ:

struct fdt_header *ufdt_apply_overlay(
        struct fdt_header *main_fdt_header,
        size_t main_fdt_size,
        void *overlay_fdt,
        size_t overlay_size);

প্যারামিটার main_fdt_header হল প্রধান DT এবং overlay_fdt হল একটি .dtbo ফাইলের বিষয়বস্তু ধারণকারী বাফার। রিটার্ন মান হল একটি নতুন বাফার যাতে মার্জড ডিটি (বা ত্রুটির ক্ষেত্রে null ) থাকে। মার্জ করা DT FDT-তে ফর্ম্যাট করা হয়, যা আপনি কার্নেল শুরু করার সময় কার্নেলে পাঠাতে পারেন।

রিটার্ন মান থেকে নতুন বাফারটি dto_malloc() দ্বারা তৈরি করা হয়েছে, যা বুটলোডারে libufdt পোর্ট করার সময় আপনার প্রয়োগ করা উচিত। রেফারেন্স বাস্তবায়নের জন্য, sysdeps/libufdt_sysdeps_*.c দেখুন।

রুট নোড সীমাবদ্ধতা

আপনি মূল DT-এর রুট নোডে একটি নতুন নোড বা সম্পত্তি ওভারলে করতে পারবেন না কারণ ওভারলে অপারেশনগুলি লেবেলের উপর নির্ভর করে। যেহেতু প্রধান DT-কে অবশ্যই একটি লেবেল সংজ্ঞায়িত করতে হবে এবং ওভারলে DT নোডগুলিকে লেবেল দিয়ে ওভারলে করার জন্য বরাদ্দ করে, আপনি রুট নোডের জন্য একটি লেবেল দিতে পারবেন না (এবং তাই রুট নোডকে ওভারলে করতে পারবেন না)।

SoC বিক্রেতাদের অবশ্যই প্রধান DT-এর ওভারলেয়িং ক্ষমতা সংজ্ঞায়িত করতে হবে; ODM/OEM শুধুমাত্র SoC বিক্রেতা দ্বারা সংজ্ঞায়িত লেবেল সহ নোডগুলি যুক্ত বা ওভাররাইড করতে পারে৷ একটি সমাধান হিসাবে, আপনি বেস ডিটিতে রুট নোডের নীচে একটি odm নোড সংজ্ঞায়িত করতে পারেন, নতুন নোড যুক্ত করতে ওভারলে DT-তে সমস্ত ODM নোডকে সক্ষম করে৷ বিকল্পভাবে, আপনি বেস ডিটিতে সমস্ত SoC-সম্পর্কিত নোডগুলিকে নীচে বর্ণিত হিসাবে রুট নোডের অধীনে একটি soc নোডে রাখতে পারেন:

main.dts overlay.dts
/dts-v1/;

/ {
    compatible = "corp,bar";
    ...

    chosen: chosen {
        bootargs = "...";
    };

    /* nodes for all soc nodes */
    soc {
        ...
        soc_device@0: soc_device@0 {
            compatible = "corp,bar";
            ...
        };
        ...
    };

    odm: odm {
        /* reserved for overlay by odm */
    };
};
/dts-v1/;
/plugin/;

/ {
};

&chosen {
    bootargs_ex = "...";
};

&odm {
    odm_device@0 {
        ...
    };
    ...
};

সংকুচিত ওভারলে ব্যবহার করে

ডিভাইস ট্রি টেবিল হেডারের সংস্করণ 1 ব্যবহার করার সময় Android 9 DTBO ছবিতে সংকুচিত ওভারলে ব্যবহার করার জন্য সমর্থন যোগ করে। DTBO হেডার v1 ব্যবহার করার সময়, dt_table_entry- এ পতাকা ক্ষেত্রের চারটি সর্বনিম্ন উল্লেখযোগ্য বিট DT এন্ট্রির কম্প্রেশন বিন্যাস নির্দেশ করে।

struct dt_table_entry_v1 {
  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 flags;      /* For version 1 of dt_table_header, the 4 least significant bits
                        of 'flags' will be used to indicate the compression
                        format of the DT entry as per the enum 'dt_compression_info' */
  uint32_t custom[3];  /* optional, must be zero if unused */
};

বর্তমানে, zlib এবং gzip কম্প্রেশন সমর্থিত।

enum dt_compression_info {
    NO_COMPRESSION,
    ZLIB_COMPRESSION,
    GZIP_COMPRESSION
};

অ্যান্ড্রয়েড 9 আপনাকে ওভারলে অ্যাপ্লিকেশনের সঠিকতা যাচাই করতে সহায়তা করার জন্য VtsFirmwareDtboVerification পরীক্ষায় সংকুচিত ওভারলে পরীক্ষা করার জন্য সমর্থন যোগ করে।

নমুনা DTO বাস্তবায়ন

নিম্নলিখিত নির্দেশাবলী আপনাকে libufdt (নীচের নমুনা কোড) সহ DTO-এর একটি নমুনা বাস্তবায়নের মাধ্যমে নিয়ে যায়।

নমুনা DTO নির্দেশাবলী

  1. লাইব্রেরি অন্তর্ভুক্ত করুন। libufdt ব্যবহার করতে, ডেটা স্ট্রাকচার এবং API-এর জন্য libfdt অন্তর্ভুক্ত করুন:
    #include <libfdt.h>
    #include <ufdt_overlay.h>
    
  2. প্রধান ডিটি এবং ওভারলে ডিটি লোড করুন। স্টোরেজ থেকে মেমরিতে .dtb এবং .dtbo লোড করুন (সঠিক পদক্ষেপগুলি আপনার ডিজাইনের উপর নির্ভর করে)। এই মুহুর্তে, আপনার কাছে .dtb / .dtbo এর বাফার এবং আকার থাকা উচিত :
    main_size = my_load_main_dtb(main_buf, main_buf_size)
    
    overlay_size = my_load_overlay_dtb(overlay_buf, overlay_buf_size);
    
  3. DTs ওভারলে:
    1. প্রধান DT এর জন্য FDT হেডার পেতে ufdt_install_blob() ব্যবহার করুন:
      main_fdt_header = ufdt_install_blob(main_buf, main_size);
      main_fdt_size = main_size;
      
    2. FDT ফর্ম্যাটে মার্জড ডিটি পেতে DTO-তে ufdt_apply_overlay() কল করুন:
      merged_fdt = ufdt_apply_overlay(main_fdt_header, main_fdt_size,
                                      overlay_buf, overlay_size);
      
    3. dtc_totalsize() এর আকার পেতে merged_fdt ব্যবহার করুন :
      merged_fdt_size = dtc_totalsize(merged_fdt);
      
    4. কার্নেল শুরু করতে মার্জড ডিটি পাস করুন:
      my_kernel_entry(0, machine_type, merged_fdt);
      

নমুনা DTO কোড

#include <libfdt.h>
#include <ufdt_overlay.h>

…

{
  struct fdt_header *main_fdt_header;
  struct fdt_header *merged_fdt;

  /* load main dtb into memory and get the size */
  main_size = my_load_main_dtb(main_buf, main_buf_size);

  /* load overlay dtb into memory and get the size */
  overlay_size = my_load_overlay_dtb(overlay_buf, overlay_buf_size);

  /* overlay */
  main_fdt_header = ufdt_install_blob(main_buf, main_size);
  main_fdt_size = main_size;
  merged_fdt = ufdt_apply_overlay(main_fdt_header, main_fdt_size,
                                  overlay_buf, overlay_size);
  merged_fdt_size = dtc_totalsize(merged_fdt);

  /* pass to kernel */
  my_kernel_entry(0, machine_type, merged_fdt);
}