أقسام تمهيد البائع

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

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

هيكل التقسيم

قسم تمهيد البائع هو A/B'd مع A/B افتراضي ومحمي بواسطة Android Verified Boot.

الإصدار 3

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

قسم عدد الصفحات
رأس تمهيد البائع (عدد الصفحات) n = (2112 + page_size - 1) / page_size
قرص ذاكرة البائع (o الصفحات) o = (vendor_ramdisk_size + page_size - 1) / page_size
DTB (صفحات ص) p = (dtb_size + page_size - 1) / page_size

الإصدار 4

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

قسم عدد الصفحات
رأس تمهيد البائع (عدد الصفحات) n = (2128 + page_size - 1) / page_size
أجزاء قرص ذاكرة المورد (صفحات) o = (vendor_ramdisk_size + page_size - 1) / page_size
DTB (صفحات ص) p = (dtb_size + page_size - 1) / page_size
جدول قرص ذاكرة المورد (صفحات q) q = (vendor_ramdisk_table_size + page_size - 1) / page_size
Bootconfig (صفحات ص) 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 على وحدات بت خاصة بالنظام الأساسي. يجب على أداة تحميل التشغيل دائمًا تحميلها في الذاكرة.
    • تحتوي أقراص الذاكرة VENDOR_RAMDISK_TYPE_RECOVERY على موارد الاسترداد. يجب على أداة تحميل التشغيل تحميل هذه الملفات في الذاكرة عند التشغيل في الاسترداد.
    • تحتوي أقراص الذاكرة VENDOR_RAMDISK_TYPE_DLKM على وحدات kernel ديناميكية قابلة للتحميل.
  • ramdisk_name هو اسم فريد لـ ramdisk.
  • يعد board_id متجهًا لمعرفات الأجهزة المحددة من قبل البائع.

دعم محمل الإقلاع

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

يجب أن يقوم برنامج تحميل التشغيل بتحميل قرص ذاكرة الوصول العشوائي العام في الذاكرة مباشرة بعد قرص ذاكرة البائع (تدعم تنسيقات CPIO وGzip وlz4 هذا النوع من التسلسل). لا تقم بمحاذاة صورة قرص الذاكرة العامة أو إدخال أي مسافة أخرى بينها وبين نهاية قرص الذاكرة الخاص بالمورد في الذاكرة. بعد فك ضغط النواة، تقوم باستخراج الملف المتسلسل إلى initramfs ، مما يؤدي إلى بنية ملف عبارة عن قرص ذاكرة عام متراكب على بنية ملف قرص ذاكرة المورد.

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

تم شرح متطلبات أداة تحميل التشغيل لدعم bootconfig في صفحة تنفيذ Bootconfig .

أقراص رام متعددة البائعين (الإصدار 4)

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

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

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

بناء الدعم

لتنفيذ دعم تمهيد البائع لجهاز:

  • قم بتعيين BOARD_BOOT_HEADER_VERSION على 3 أو أكبر.

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

  • قم بتعيين BOARD_VENDOR_BOOTIMAGE_PARTITION_SIZE على الحجم المناسب لجهازك، مع الأخذ في الاعتبار وحدات kernel التي يجب أن تكون موجودة على قرص ذاكرة الوصول العشوائي الخاص بالمورد.

  • قم بتحديث 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 على قائمة بأسماء أجزاء قرص ذاكرة الوصول العشوائي الخاصة بالمورد والتي سيتم تضمينها في vendor_boot .

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

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

  • قم بتعيين BOARD_VENDOR_RAMDISK_FRAGMENT.$(vendor_ramdisk).MKBOOTIMG_ARGS على وسيطات mkbootimg . هذه هي الوسيطات --board_id[0-15] و-- --ramdisk_type لجزء ramdisk الخاص بالمورد. بالنسبة إلى ramdisk لمورد 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 الناتج على جزأين من قرص ذاكرة الوصول العشوائي الخاص بالمورد. الأول هو قرص الذاكرة "الافتراضي"، الذي يحتوي على دليل DLKM baz وبقية الملفات في $(TARGET_VENDOR_RAMDISK_OUT) . والثاني هو dlkm_foobar ramdisk، الذي يحتوي على أدلة DLKM foo و bar ، والإعدادات الافتراضية --ramdisk_type هي DLKM .