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