قدم 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
.