أقسام التشغيل الخاصة بالمورّد

طرَح نظام Android 11 مفهوم النواة العامة (Kernel) صورة (GKI) لتفعيل تشغيل جهاز عشوائي باستخدام GKI، يمكن لأجهزة Android 11 استخدام الإصدار 3 من عنوان صورة التمهيد. ضِمن 3، يتم حذف كل المعلومات الخاصة بالمورّد من boot ونقلت الموقع إلى قسم vendor_boot جديد. يجب أن يتوافق جهاز ARM64 الذي يعمل بالإصدار 11 من نظام التشغيل Android على نواة Linux 5.4 مع القسم vendor_boot وتنسيق القسم boot المعدَّل لاجتياز الاختبار باستخدام GKI.

يمكن لأجهزة Android 12 استخدام الإصدار 4 من عنوان صورة التمهيد، الذي يتيح تضمين عدة أقراص RAM لجهات خارجية في القسم vendor_boot . يتم تسلسل عدة أجزاء من ذاكرة التخزين المؤقت للجهاز من المورّد بعد بعضها في قسم ذاكرة التخزين المؤقت للجهاز من المورّد. يُستخدم جدول ذاكرة التخزين المؤقت للبائع لوصف تخطيط قسم ذاكرة التخزين المؤقت للبائع والبيانات الوصفية لكل قاعدة بيانات خاصة بالبائع .

بنية التقسيم

يتم تقسيم قسم التمهيد الخاص بالمورّد إلى قسمَين A/B باستخدام ميزة A/B الافتراضي ويتم حمايته من خلال ميزة "التمهيد التحقق منه" في Android .

الإصدار 3

يتألّف القسم من عنوان ومساحة تخزين مؤقت للمورّد ومجموعة بيانات شجرة الجهاز (DTB).

القسم عدد الصفحات
عنوان تشغيل المورّد (عدد الصفحات) n = (2112 + page_size - 1) / page_size
ذاكرة التخزين المؤقت للوسائط الرام (o صفحات) o = (vendor_ramdisk_size + page_size - 1) / page_size
DTB (صفحات p) p = (dtb_size + page_size - 1) / page_size

الإصدار 4

يتكون القسم من رأس، وقسم قرص ذاكرة المورد (يتكوّن من جميع أجزاء ذاكرة الوصول العشوائي الخاصة بالمورد، والمتسلسلة، والكائن الثنائي الكبير لشجرة الجهاز (DTB)، جدول ذاكرة التخزين المؤقت للبائع.

القسم عدد الصفحات
رأس التمهيد الخاص بالمورّد (n صفحة) n = (2128 + page_size - 1) / page_size
أجزاء ذاكرة التخزين المؤقت العشوائي للمورّد (o صفحات) o = (vendor_ramdisk_size + page_size - 1) / page_size
DTB (صفحات p) p = (dtb_size + page_size - 1) / page_size
جدول ذاكرة التخزين المؤقت للمورّدين (صفحات Q) q = (vendor_ramdisk_table_size + page_size - 1) / page_size
Bootconfig (صفحات r) r = (bootconfig_size + page_size - 1) / page_size

عنوان تشغيل المورّد

تتألف محتويات عنوان قسم التمهيد الخاص بالمورّد بشكل أساسي من البيانات التي تم نقلها إلى هناك من عنوان صورة التمهيد. ويحتوي أيضًا على معلومات عن ذاكرة الوصول العشوائي للمورّد.

الإصدار 3

struct vendor_boot_img_hdr_v3
{
#define VENDOR_BOOT_MAGIC_SIZE 8
    uint8_t magic[VENDOR_BOOT_MAGIC_SIZE];
    uint32_t header_version;
    uint32_t page_size;           /* flash page size we assume */

    uint32_t kernel_addr;         /* physical load addr */
    uint32_t ramdisk_addr;        /* physical load addr */

    uint32_t vendor_ramdisk_size; /* size in bytes */

#define VENDOR_BOOT_ARGS_SIZE 2048
    uint8_t cmdline[VENDOR_BOOT_ARGS_SIZE];

    uint32_t tags_addr;           /* physical addr for kernel tags */

#define VENDOR_BOOT_NAME_SIZE 16
    uint8_t name[VENDOR_BOOT_NAME_SIZE]; /* asciiz product name */
    uint32_t header_size;         /* size of vendor boot image header in
                                   * bytes */
    uint32_t dtb_size;            /* size of dtb image */
    uint64_t dtb_addr;            /* physical load address */

};

الإصدار 4

struct vendor_boot_img_hdr_v4
{
#define VENDOR_BOOT_MAGIC_SIZE 8
    uint8_t magic[VENDOR_BOOT_MAGIC_SIZE];
    uint32_t header_version;
    uint32_t page_size;           /* flash page size we assume */

    uint32_t kernel_addr;         /* physical load addr */
    uint32_t ramdisk_addr;        /* physical load addr */

    uint32_t vendor_ramdisk_size; /* size in bytes */

#define VENDOR_BOOT_ARGS_SIZE 2048
    uint8_t cmdline[VENDOR_BOOT_ARGS_SIZE];

    uint32_t tags_addr;           /* physical addr for kernel tags */

#define VENDOR_BOOT_NAME_SIZE 16
    uint8_t name[VENDOR_BOOT_NAME_SIZE]; /* asciiz product name */
    uint32_t header_size;         /* size of vendor boot image header in
                                   * bytes */
    uint32_t dtb_size;            /* size of dtb image */
    uint64_t dtb_addr;            /* physical load address */

    uint32_t vendor_ramdisk_table_size; /* size in bytes for the vendor ramdisk table */
    uint32_t vendor_ramdisk_table_entry_num; /* number of entries in the vendor ramdisk table */
    uint32_t vendor_ramdisk_table_entry_size; /* size in bytes for a vendor ramdisk table entry */
    uint32_t bootconfig_size; /* size in bytes for the bootconfig section */
};

#define VENDOR_RAMDISK_TYPE_NONE 0
#define VENDOR_RAMDISK_TYPE_PLATFORM 1
#define VENDOR_RAMDISK_TYPE_RECOVERY 2
#define VENDOR_RAMDISK_TYPE_DLKM 3

struct vendor_ramdisk_table_entry_v4
{
    uint32_t ramdisk_size; /* size in bytes for the ramdisk image */
    uint32_t ramdisk_offset; /* offset to the ramdisk image in vendor ramdisk section */
    uint32_t ramdisk_type; /* type of the ramdisk */
#define VENDOR_RAMDISK_NAME_SIZE 32
    uint8_t ramdisk_name[VENDOR_RAMDISK_NAME_SIZE]; /* asciiz ramdisk name */

#define VENDOR_RAMDISK_TABLE_ENTRY_BOARD_ID_SIZE 16
    // Hardware identifiers describing the board, soc or platform which this
    // ramdisk is intended to be loaded on.
    uint32_t board_id[VENDOR_RAMDISK_TABLE_ENTRY_BOARD_ID_SIZE];
};
  • vendor_ramdisk_size هو الحجم الإجمالي لجميع أجزاء ذاكرة الوصول العشوائي الخاصة بالمورّدين.
  • تشير السمة ramdisk_type إلى نوع القرص، والقيم المحتملة هي:
    • تشير السمة VENDOR_RAMDISK_TYPE_NONE إلى أنّ القيمة غير محدّدة.
    • VENDOR_RAMDISK_TYPE_PLATFORM تحتوي ملفات RAMD على وحدات بت خاصة بالنظام الأساسي. ويجب أن يحمّل برنامج الإقلاع دائمًا هذه الملفات في الذاكرة.
    • تحتوي VENDOR_RAMDISK_TYPE_RECOVERY ملفات RAMD على موارد استرداد. يجب أن يحمِّل برنامج الإقلاع هذه الملفات إلى الذاكرة عند التمهيد إلى وضع الاسترداد.
    • VENDOR_RAMDISK_TYPE_DLKM تحتوي أقراص RAM على وحدات أساسية قابلة للتحميل ديناميكيًا.
  • "ramdisk_name" هو اسم فريد للقرع.
  • board_id هو متجه لمعرّفات الأجهزة التي يحدّدها المورّد.

دعم برنامج الإقلاع

بما أنّ قسم التمهيد الخاص بالمورّد يحتوي على معلومات (مثل حجم صفحة الفلاش، والنواة، وعناوين تحميل قرص التخزين المؤقت في ذاكرة الوصول العشوائي، وملف DTB نفسه) كانت متوفّرة سابقًا في قسم التمهيد، يجب أن يصل مشغّل الإقلاع إلى كلّ من قسم التمهيد وقسم التمهيد الخاص بالمورّد للحصول على بيانات كافية لإكمال عملية التمهيد.

يجب أن يحمِّل برنامج الإقلاع قرص ذاكرة التخزين المؤقت العام في الذاكرة فورًا من خلال اتّباع الخطوات التالية: القرص الكامل للمورد (تدعم تنسيقات CPIO وGzip وlz4 هذا النوع من والتسلسل). لا تُعدِّل تنسيق صفحة صورة ذاكرة التخزين المؤقت العشوائي العامة أو تُدرِج أي مساحة أخرى بينها وبين نهاية ذاكرة التخزين المؤقت العشوائي الخاصة بالمورّد في الذاكرة. بعد إزالة ضغط ملف التمهيد، يُستخرج الملف المجمّع إلى ملف initramfs، مما يؤدي إلى إنشاء بنية ملف تمثل ذاكرة وصول عشوائي (RAM) عامة مضمَّنة في بنية ملف ذاكرة وصول عشوائي (RAM) الخاصة بالمورّد.

نظرًا لأنه يتم دمج ramdisk العام وجدول ذاكرة البائع، فيجب أن يكونا في بنفس التنسيق. تستخدم صورة تمهيد GKI قرص RAM عامًا مضغوطًا بتنسيق lz4، يجب أن يستخدم الجهاز المتوافق مع GKI رمز ذاكرة وصول عشوائي (RAM) مضغوطًا من نوع lz4. تشير رسالة الأشكال البيانية لذلك موضحة أدناه.

يتم شرح متطلبات برنامج الإقلاع لتفعيل bootconfig في مقالة تنفيذ Bootconfig.

أقراص RAM متعددة المورّدين (الإصدار 4)

فمع الإصدار 4 من رأس صورة التشغيل، يمكن لبرنامج الإقلاع تحديد مجموعة فرعية أو جميع عمليات الهجرة إلى جانب المورد لتحميلها مثل initramfs أثناء وقت التشغيل. تشير رسالة الأشكال البيانية يحتوي جدول رامديسك الخاص بالبائع على بيانات وصفية لكل ذاكرة وصول عشوائي، ويمكن أن يساعد في برنامج الإقلاع في تحديد ملفات الهضم التي سيتم تحميلها. يمكن لبرنامج الإقلاع تحديد من أجل تحميل ملفات ramdisk المحددة للبائع، طالما أن القرص العام آخر تحميل.

على سبيل المثال، يمكن أن يحذف برنامج الإقلاع ملفات RAMD من النوع الذي يتم تحميله VENDOR_RAMDISK_TYPE_RECOVERY أثناء التشغيل العادي للحفاظ على الموارد، لذلك عمليات إعادة التوجيه للبائعين من النوع VENDOR_RAMDISK_TYPE_PLATFORM يتم تحميل VENDOR_RAMDISK_TYPE_DLKM في الذاكرة. من ناحية أخرى، يتم تحميل ملف ‎ramdisk الخاص بالمورّد من النوع VENDOR_RAMDISK_TYPE_PLATFORM وVENDOR_RAMDISK_TYPE_RECOVERY وVENDOR_RAMDISK_TYPE_DLKM في الذاكرة عند التمهيد في وضع recovery .

بدلاً من ذلك، يمكن لبرنامج الإقلاع تجاهل جدول ذاكرة التخزين المؤقت للمورّد وتحميل قسم ذاكرة التخزين المؤقت للمورّد بالكامل. وينتج عن ذلك التأثير نفسه الذي يؤديه تحميل جميع أجزاء قرص ذاكرة المورد في القسم vendor_boot.

إنشاء الدعم

لتنفيذ ميزة "تشغيل الجهاز من خلال موفِّر البرامج الأساسية" لجهاز:

  • اضبط BOARD_BOOT_HEADER_VERSION على 3 أو أعلى.

  • اضبط BOARD_RAMDISK_USE_LZ4 على true إذا كان جهازك متوافقًا مع GKI، أو إذا كان يستخدم ملف ramdisk عامًا مضغوطًا بتنسيق lz4.

  • اضبط BOARD_VENDOR_BOOTIMAGE_PARTITION_SIZE على حجم مناسب لجهازك، مع مراعاة وحدات kernel التي يجب أن تنتقل إلى ذاكرة الوصول العشوائي (RAM) الخاصة بالمورّد.

  • يجب تعديل "AB_OTA_PARTITIONS" لتضمين vendor_boot وأي منتجات خاصة بالمورّدين. قوائم أقسام OTA على الجهاز.

  • انسخ fstab على جهازك إلى /first_stage_ramdisk في قسم vendor_boot ، وليس في قسم boot. على سبيل المثال: $(LOCAL_PATH)/fstab.hardware:$(TARGET_COPY_OUT_VENDOR_RAMDISK)/first_stage_ramdisk/fstab.$(PRODUCT_PLATFORM)

لتضمين عدة خطط طارئة للمورّدين في vendor_boot:

  • اضبط السمة BOARD_BOOT_HEADER_VERSION على 4.
  • اضبط BOARD_VENDOR_RAMDISK_FRAGMENTS على قائمة بأسماء أجزاء ملف ramdisk اللوجي الخاص بالمورّد المطلوب تضمينها في vendor_boot.

  • لإضافة ذاكرة وصول عشوائي للبائع مسبقًا، قم بتعيين BOARD_VENDOR_RAMDISK_FRAGMENT.$(vendor_ramdisk).PREBUILT إلى العناصر التي تم إنشاؤها مسبقًا .

  • لإضافة ذاكرة وصول عشوائي لمورِّد DLKM، اضبط في BOARD_VENDOR_RAMDISK_FRAGMENT.$(vendor_ramdisk).KERNEL_MODULE_DIRS قائمة بدلائل وحدات النواة المراد تضمينها.

  • ضبط BOARD_VENDOR_RAMDISK_FRAGMENT.$(vendor_ramdisk).MKBOOTIMG_ARGS على mkbootimg وسيطة. هذه هي الوسيطات --board_id[0-15] و--ramdisk_type لجزء ذاكرة التخزين المؤقت للجهاز من المورّد. بالنسبة إلى قرص التخزين المؤقت لجهة تصنيع DLKM، سيكون القيمة التلقائية لسمة --ramdisk_type هي DLKM في حال عدم تحديد قيمة أخرى.

لإنشاء مراجع استرداد الحساب كقرص تخزين مستقل في recovery في vendor_boot:

  • اضبط BOARD_BOOT_HEADER_VERSION على 4.
  • اضبط السمة BOARD_MOVE_RECOVERY_RESOURCES_TO_VENDOR_BOOT على true.
  • اضبط السمة BOARD_INCLUDE_RECOVERY_RAMDISK_IN_VENDOR_BOOT على true.
  • يؤدي ذلك إلى إضافة جزء في ذاكرة الوصول العشوائي للمورّد، حيث يكون ramdisk_name هو recovery "ramdisk_type" هي VENDOR_RAMDISK_TYPE_RECOVERY. يحتوي الهرم بعد ذلك على جميع ملفات الاسترداد، وهي الملفات التي يتم تثبيتها ضمن $(TARGET_RECOVERY_ROOT_OUT)

وسيطات mkbootimg

الوسيطة الوصف
--ramdisk_type نوع قرص التخزين المؤقت في ذاكرة الوصول العشوائي، يمكن أن يكون أحد القيم التالية: NONE PLATFORM أو RECOVERY أو DLKM.
--board_id[0-15] حدِّد متجه board_id، الذي يتم ضبطه تلقائيًا على 0.

وفي ما يلي مثال على عملية الضبط:

BOARD_KERNEL_MODULE_DIRS := foo bar baz
BOARD_BOOT_HEADER_VERSION := 4
BOARD_VENDOR_RAMDISK_FRAGMENTS := dlkm_foobar
BOARD_VENDOR_RAMDISK_FRAGMENT.dlkm_foobar.KERNEL_MODULE_DIRS := foo bar
BOARD_VENDOR_RAMDISK_FRAGMENT.dlkm_foobar.MKBOOTIMG_ARGS := --board_id0 0xF00BA5 --board_id1 0xC0FFEE

سيتضمّن vendor_boot الناتج جزءَين من ذاكرة التخزين المؤقت للجهاز من المورّد. تشير رسالة الأشكال البيانية الأول هو "الافتراضي" ramdisk، الذي يحتوي على دليل DLKM baz باقي الملفات في $(TARGET_VENDOR_RAMDISK_OUT). أما القسم الثاني، فهو ملف ذاكرة التخزين المؤقت dlkm_foobar الذي يحتوي على دليلَي DLKM foo وbar، ويُعدّ --ramdisk_type الإعداد التلقائي لDLKM.