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

قدم Android 11 مفهوم Generic Kernel Image (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 . يتم تجميع أجزاء ramdisk المتعددة الخاصة بالمورد واحدة تلو الأخرى في قسم ramdisk الخاص بالمورد. يتم استخدام جدول ramdisk الخاص بالمورد لوصف تخطيط قسم ramdisk الخاص بالمورد والبيانات الوصفية لكل جزء من أجزاء ramdisk الخاصة بالمورد.

هيكل التقسيم

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

الإصدار 3

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

الجزء عدد الصفحات
رأس تمهيد البائع (عدد الصفحات) n = (2112 + page_size - 1) / page_size
البائع ramdisk (صفحات o) o = (vendor_ramdisk_size + page_size - 1) / page_size
DTB (ص الصفحات) p = (dtb_size + page_size - 1) / page_size

الإصدار 4

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

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

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

تتكون محتويات رأس قسم تمهيد البائع بشكل أساسي من البيانات التي تم نقلها هناك من رأس صورة التمهيد . كما يحتوي على معلومات حول ramdisk البائع.

الإصدار 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 على وحدات بت خاصة بالنظام الأساسي. يجب أن يقوم برنامج bootloader بتحميلها دائمًا في الذاكرة.
    • تحتوي أقراص VENDOR_RAMDISK_TYPE_RECOVERY على موارد الاسترداد. يجب أن يقوم برنامج bootloader بتحميل هذه الملفات في الذاكرة عند التشغيل في برنامج الاسترداد.
    • تحتوي أقراص VENDOR_RAMDISK_TYPE_DLKM ramdisks على وحدات نواة ديناميكية قابلة للتحميل.
  • ramdisk_name هو اسم فريد للذاكرة ramdisk.
  • board_id عبارة عن متجه لمعرفات الأجهزة التي يحددها البائع.

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

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

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

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

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

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

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

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

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

بناء الدعم

لتنفيذ دعم تمهيد المورد لجهاز:

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

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

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

  • قم بتحديث 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 .

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

  • لإضافة RAMDISK لبائع 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 الخاص بالمورد الذي يكون ramdisk_name به هو recovery و ramdisk_type هو VENDOR_RAMDISK_TYPE_RECOVERY . ثم يحتوي ramdisk بعد ذلك على جميع ملفات الاسترداد ، وهي ملفات مثبتة تحت $(TARGET_RECOVERY_ROOT_OUT) .

الحجج mkbootimg

جدال حاد وصف
--ramdisk_type يمكن أن يكون نوع ramdisk من 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 ramdisk ، والذي يحتوي على مجلدي DLKM foo و bar ، بينما --ramdisk_type الافتراضية DLKM .