اندروید ۱۱ مفهوم تصویر هسته عمومی (GKI) را معرفی کرد. برای فعال کردن بوت شدن یک دستگاه دلخواه با GKI، دستگاههای اندروید ۱۱ میتوانند از هدر تصویر بوت نسخه ۳ استفاده کنند. در نسخه ۳، تمام اطلاعات خاص فروشنده از پارتیشن boot حذف شده و به یک پارتیشن جدید vendor_boot منتقل میشوند. یک دستگاه ARM64 که با اندروید ۱۱ روی هسته لینوکس ۵.۴ راهاندازی میشود، باید از پارتیشن vendor_boot و فرمت پارتیشن boot بهروزرسانیشده پشتیبانی کند تا آزمایش با GKI را با موفقیت پشت سر بگذارد.
دستگاههای اندروید ۱۲ میتوانند از هدر تصویر بوت نسخه ۴ استفاده کنند که از گنجاندن چندین ramdisk از شرکتهای مختلف در پارتیشن vendor_boot پشتیبانی میکند. چندین قطعه ramdisk از شرکتهای مختلف، یکی پس از دیگری در بخش ramdisk از شرکتهای مختلف به هم متصل میشوند. یک جدول ramdisk از شرکتهای مختلف برای توصیف طرحبندی بخش ramdisk از شرکتهای مختلف و فرادادههای هر قطعه ramdisk از شرکتهای مختلف استفاده میشود.
ساختار پارتیشن
پارتیشن بوت فروشنده با A/B مجازی A/B-ed شده و توسط Android Verified Boot محافظت میشود.
نسخه ۳
این پارتیشن شامل یک هدر، ramdisk فروشنده و قطعه درخت دستگاه (DTB) است.
| بخش | تعداد صفحات |
|---|---|
| سربرگ بوت فروشنده (n صفحه) | n = (2112 + 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 فروشنده (شامل تمام قطعات ramdisk فروشنده، به هم پیوسته)، لکه درخت دستگاه (DTB) و جدول ramdisk فروشنده است.
| بخش | تعداد صفحات |
|---|---|
| سربرگ بوت فروشنده (n صفحه) | n = (2128 + page_size - 1) / page_size |
| قطعات رمدیسک فروشنده (o صفحه) | 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 |
| پیکربندی بوت (صفحات r) | r = (bootconfig_size + page_size - 1) / page_size |
هدر بوت فروشنده
محتویات هدر پارتیشن بوت فروشنده عمدتاً شامل دادههایی است که از هدر تصویر بوت به آنجا منتقل شدهاند. همچنین حاوی اطلاعاتی در مورد رمدیسک فروشنده است.
نسخه ۳
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 */
};
نسخه ۴
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 فروشنده است. -
ramdisk_typeنوع ramdisk را نشان میدهد، مقادیر ممکن عبارتند از:-
VENDOR_RAMDISK_TYPE_NONEنشان میدهد که مقدار مشخص نشده است. -
VENDOR_RAMDISK_TYPE_PLATFORMramdiskها حاوی بیتهای مخصوص پلتفرم هستند. بوتلودر باید همیشه این بیتها را در حافظه بارگذاری کند. -
VENDOR_RAMDISK_TYPE_RECOVERYramdiskها حاوی منابع بازیابی هستند. بوتلودر باید هنگام بوت شدن به حالت بازیابی، این منابع را در حافظه بارگذاری کند. - رمدیسکهای
VENDOR_RAMDISK_TYPE_DLKMحاوی ماژولهای هسته قابل بارگذاری پویا هستند.
-
-
ramdisk_nameنام منحصر به فرد ramdisk است. -
board_idاز شناسههای سختافزاری تعریفشده توسط فروشنده است.
پشتیبانی از بوت لودر
از آنجا که پارتیشن بوت فروشنده حاوی اطلاعاتی (مانند اندازه صفحه فلش، هسته، آدرسهای بارگذاری رمدیسک، خود DTB) است که قبلاً در پارتیشن بوت وجود داشته است، بوتلودر باید به هر دو پارتیشن بوت و بوت فروشنده دسترسی داشته باشد تا دادههای کافی برای تکمیل بوت داشته باشد.
بوت لودر باید ramdisk عمومی را بلافاصله پس از ramdisk فروشنده در حافظه بارگذاری کند (فرمتهای CPIO، Gzip و lz4 از این نوع الحاق پشتیبانی میکنند). تصویر ramdisk عمومی را صفحه بندی نکنید یا هیچ فاصله دیگری بین آن و انتهای ramdisk فروشنده در حافظه قرار ندهید. پس از اینکه هسته از حالت فشرده خارج شد، فایل الحاق شده را در یک initramfs استخراج میکند، که منجر به ساختار فایلی میشود که یک ramdisk عمومی است که روی ساختار فایل ramdisk فروشنده قرار گرفته است.
از آنجا که ramdisk عمومی و ramdisk فروشنده به هم متصل میشوند، باید فرمت یکسانی داشته باشند. تصویر بوت GKI از یک ramdisk عمومی فشردهشده با lz4 استفاده میکند، بنابراین دستگاهی که با GKI سازگار است باید از یک ramdisk فروشنده فشردهشده با lz4 استفاده کند. پیکربندی این مورد در زیر نشان داده شده است.
الزامات بوت لودر برای پشتیبانی از bootconfig در Implement Bootconfig توضیح داده شده است.
رمدیسکهای چندفروشندهای (نسخه ۴)
با هدر تصویر بوت نسخه ۴، بوتلودر میتواند یک زیرمجموعه یا تمام ramdiskهای فروشنده را برای بارگذاری به عنوان initramfs در طول زمان بوت انتخاب کند. جدول ramdisk فروشنده شامل ابردادههای هر ramdisk است و میتواند به بوتلودر در تصمیمگیری برای بارگذاری ramdiskها کمک کند. بوتلودر میتواند ترتیب بارگذاری ramdiskهای فروشنده انتخاب شده را تعیین کند، البته تا زمانی که ramdisk عمومی آخرین بار بارگذاری شود.
برای مثال، بوتلودر میتواند بارگذاری رمدیسکهای فروشنده از نوع VENDOR_RAMDISK_TYPE_RECOVERY را در طول بوت معمولی حذف کند تا در منابع صرفهجویی شود، بنابراین فقط رمدیسکهای فروشنده از نوع VENDOR_RAMDISK_TYPE_PLATFORM و VENDOR_RAMDISK_TYPE_DLKM در حافظه بارگذاری میشوند. از سوی دیگر، رمدیسکهای فروشنده از نوع VENDOR_RAMDISK_TYPE_PLATFORM ، VENDOR_RAMDISK_TYPE_RECOVERY و VENDOR_RAMDISK_TYPE_DLKM هنگام بوت شدن در حالت ریکاوری در حافظه بارگذاری میشوند.
از طرف دیگر، بوتلودر میتواند جدول ramdisk مربوط به vendor را نادیده بگیرد و کل بخش ramdisk مربوط به vendor را بارگذاری کند. این کار همان تأثیر بارگذاری تمام قطعات ramdisk مربوط به vendor در پارتیشن vendor_boot دارد.
پشتیبانی ایجاد کنید
برای پیادهسازی پشتیبانی بوت فروشنده برای یک دستگاه:
مقدار
BOARD_BOOT_HEADER_VERSIONروی3یا بیشتر تنظیم کنید.اگر دستگاه شما با GKI سازگار است، یا اگر از یک ramdisk عمومی فشردهشده با lz4 استفاده میکند،
BOARD_RAMDISK_USE_LZ4را رویtrueتنظیم کنید.با توجه به ماژولهای هسته که باید روی ramdisk سازنده قرار گیرند، اندازه
BOARD_VENDOR_BOOTIMAGE_PARTITION_SIZEرا روی اندازه مناسب برای دستگاه خود تنظیم کنید.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).
برای گنجاندن چندین ramdisk از فروشندگان مختلف در 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به لیست دایرکتوریهای ماژول هسته که باید گنجانده شوند، تنظیم کنید.آرگومانهای
BOARD_VENDOR_RAMDISK_FRAGMENT.$(vendor_ramdisk).MKBOOTIMG_ARGSرا رویmkbootimgتنظیم کنید. این آرگومانها عبارتند از--board_id[0-15]و--ramdisk_typeبرای قطعه ramdisk فروشنده. برای ramdisk فروشنده DLKM، نوع--ramdisk_typeپیشفرضDLKMخواهد بود، اگر طور دیگری مشخص نشده باشد.
برای ساخت منابع بازیابی به عنوان یک ramdisk 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 مربوط به vendor خواهد بود. اولی ramdisk "پیشفرض" است که شامل دایرکتوری DLKM baz و بقیه فایلهای موجود در $(TARGET_VENDOR_RAMDISK_OUT) میشود. دومی dlkm_foobar ramdisk است که شامل دایرکتوریهای DLKM به foo و bar است و --ramdisk_type به طور پیشفرض روی DLKM تنظیم شده است.