تحسين منظمات الاتّجار بالمخدرات

تناقش هذه الصفحة التحسينات التي يمكنك إجراؤها على تنفيذ طبقة شجرة الأجهزة (DTO)، وتصف القيود المفروضة على تراكب العقدة الجذر، وتفاصيل كيفية تكوين التراكبات المضغوطة في صورة DTBO. كما أنه يوفر عينة وتعليمات التنفيذ والتعليمات البرمجية.

سطر أوامر النواة (Kernel)

يقع سطر أوامر النواة الأصلي في شجرة الجهاز (DT) في عقدة chosen/bootargs. يجب أن يربط برنامج الإقلاع هذا الرمز مع مصادر أخرى لسطر أوامر kernel:

/dts-v1/;

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

لا يمكن لـ DTO إنشاء تسلسل للقيم من DT الرئيسي وDT المركّب، لذلك يجب عليك وضع سطر أوامر النواة الخاص بوحدة DT الرئيسية في chosen/bootargs وسطر أوامر النواة لـ DT للتراكب في chosen/bootargs_ext يمكن لبرنامج الإقلاع إجراء تسلسل للبيانات وتمرير النتيجة إلى النواة.

رئيسي.dts مركّب.dts
/dts-v1/;

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

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

ليبوفدت

في حين أن أحدث libfdt يدعم DTO، فهل يُنصح باستخدام libufdt لتنفيذ DTO؟ (مصدر AOSP على platform/system/libufdt). ينشئ libufdt بنية شجرة حقيقية (شجرة أجهزة غير مسطحة، أو ufdt) من شجرة الأجهزة المسطحة (FDT)، حتى يمكن تحسين دمج ملفين .dtb من O(N2) إلى O(N)، حيث N هو عدد العقد في الشجرة.

اختبار الأداء

في اختبار Google الداخلي، يتم استخدام libufdt على 2405. ينتج عن العُقدة .dtb و283 .dtbo DT أحجام ملف 70,618 و8,566 بايت بعد التجميع. بالمقارنة مع DTO عملية التنفيذ تم نقلها من FreeBSD (وقت التشغيل 124 ملي ثانية)، libufdt وقت تشغيل DTO: 10 ملي ثانية.

تم اختبار الأداء لأجهزة Pixel مقارنةً بـ libufdt و libfdt تأثير عدد العُقد الأساسية متشابه، ولكنه يتضمن الاختلافات التالية:

  • 500 عملية تراكب (إلحاق أو تجاوز) تستغرق وقتًا من 6 إلى 8 أضعاف الفارق
  • 1000 عملية تراكب (إلحاق أو تجاوز) تستغرق وقتًا يتراوح بين 8 أضعاف و10 مرات الفارق

مثال مع ضبط عدد الإلحاق على X:

الشكل 1. عدد الإلحاق هو X.

مثال مع تعيين عدد الإلغاء على X:

الشكل 2. عدد مرات الإلغاء هو X.

تم تطوير libufdt باستخدام بعض واجهات برمجة تطبيقات libfdt وبيانات أخرى. والهياكل. عند استخدام libufdt، يجب تضمين موقعك الإلكتروني وربطه. libfdt (ولكن في رمزك، يمكنك استخدام libfdt API لتشغيل DTB أو DTBO).

واجهة برمجة تطبيقات libufdt DTO

في ما يلي واجهة برمجة التطبيقات الرئيسية لـ DTO في libufdt:

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. القيمة المعروضة هي مورد احتياطي جديد يحتوي على دمج DT (أو null في حال حدوث خطأ). تم تنسيق DT المدمج في FDT، ويمكنك تمريره إلى النواة عند بدء تشغيل النواة.

يتم إنشاء المخزن المؤقت الجديد من القيمة المعروضة من خلال dto_malloc()، والذي يجب تنفيذه عند نقل libufdt إلى برنامج الإقلاع. لمزيد من المعلومات حول عمليات التنفيذ المرجعية، يُرجى مراجعة sysdeps/libufdt_sysdeps_*.c

قيود العُقد الجذر

لا يمكنك تركيب عقدة أو خاصية جديدة في العقدة الجذر لـ DT الرئيسي. لأن عمليات التراكب تعتمد على التسميات. نظرًا لأن DT الرئيسي يجب أن يحدد وتعيين DT المتراكب على العُقد التي سيتم تركيبها مع التسميات، لا يمكن إعطاء تسمية للعقدة الجذر (وبالتالي لا يمكن أن تقوم بتراكب الجذر العقدة).

على مورّدي المنظومة على الرقاقة (SoC) تحديد القدرة المتراكبة لتقنية DT الرئيسية. يمكن للمصنّعين الأصليين أو المصنّعين الأصليين فقط إلحاق العُقد أو إلغاؤها بالتصنيفات التي يحدّدها مورِّد المنظومة على الرقاقة (SoC). نتيجة لذلك، أُنشئت مكتبة مات بلوت ليب في يمكنك تحديد عقدة odm ضمن العقدة الجذر في DT الأساسي، مما يمكن لجميع عُقد ODM في DT تراكب إضافة عُقد جديدة. بدلاً من ذلك، يمكنك وضع جميع العُقد المرتبطة بمنظومة المنظومة على الرقاقة (SoC) في دالة التوزيع الأساسية (DT) العقدة soc ضمن العقدة الأساسية كما هو موضّح أدناه:

رئيسي.dts مركّب.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 {
        ...
    };
    ...
};

استخدام تراكبات مضغوطة

يتيح الإصدار 9 من Android استخدام العناصر المضغوطة على سطح المحتوى في صورة DTBO عند استخدام الإصدار 1 من عنوان جدول DT. عند استخدام رأس DTBO الإصدار 1، تكون وحدات البت الأربعة الأقل أهمية في حقل العلامات في dt_table_enter إلى تنسيق الضغط لإدخال 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' are 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
};

Android 9 يتيح اختبار الملفات المضغوطة استخدام عناصر مركّبة على اختبار VtsFirmwareDtboVerification لمساعدتك للتحقق من صحة التطبيق الذي يظهر على سطح الفيديو.

نموذج لتنفيذ DTO

ترشدك التعليمات التالية إلى نموذج لتنفيذ DTO. مع libufdt (يُرجى الاطّلاع على الرمز النموذجي أدناه).

نموذج تعليمات حول DTO

  1. تضمين المكتبات لاستخدام libufdt، يجب تضمين libfdt لهياكل البيانات وواجهات برمجة التطبيقات:
    #include <libfdt.h>
    #include <ufdt_overlay.h>
    
  2. تحميل DT الرئيسي وDT المركّب تحميل .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. تراكب DT:
    1. استخدِم ufdt_install_blob() للحصول على عنوان FDT لجهاز DT الرئيسي:
      main_fdt_header = ufdt_install_blob(main_buf, main_size);
      main_fdt_size = main_size;
      
    2. يمكنك الاتصال بـ ufdt_apply_overlay() للتواصل مع DTO للحصول على DT مدمج في FDT. التنسيق:
      merged_fdt = ufdt_apply_overlay(main_fdt_header, main_fdt_size,
                                      overlay_buf, overlay_size);
      
    3. استخدِم merged_fdt للحصول على حجم dtc_totalsize():
      merged_fdt_size = dtc_totalsize(merged_fdt);
      
    4. عليك اجتياز اختبار DT المدمج لبدء تشغيل النواة:
      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);
}