Android 11 مفهوم «تصویر هسته عمومی» (GKI) را معرفی کرد. برای فعال کردن راهاندازی دستگاه دلخواه با GKI، دستگاههای Android
11 میتوانند از نسخه ۳ سرصفحه تصویر راهاندازی استفاده کنند. در
نسخه ۳، همه اطلاعات مختص فروشنده از boot
بخش جدا شده و به بخش جدید vendor_boot منتقل میشود. دستگاه ARM64 که با Android 11 در هسته Linux نسخه ۵.۴ راهاندازی میشود باید از پارتیشن vendor_boot و قالب پارتیشن boot بهروزرسانیشده پشتیبانی کند تا در آزمایش با GKI موفق شود.
دستگاههای Android 12 میتوانند از نسخه ۴ سرصفحه تصویر راهاندازی استفاده کنند،
که از افزودن چندین ramdisk فروشنده در vendor_boot
بخش پشتیبانی میکند. چندین تکه ramdisk فروشنده یکی پساز دیگری در بخش ramdisk فروشنده
بههم متصل میشوند. از جدول ramdisk فروشنده برای توصیف چیدمان بخش ramdisk فروشنده و فراداده هر تکه ramdisk فروشنده استفاده میشود.
ساختار پارتیشن
پارتیشن راهاندازی فروشنده با A/B مجازی A/B میشود و با «راهاندازی درستیسنجیشده Android» محافظت میشود.
نسخه ۳
این پارتیشن شامل یک سرایند، دیسک مجازی فروشنده، و حباب ساختار درختی دستگاه (DTB) است.
| بخش | تعداد صفحهها |
|---|---|
| سرصفحه راهاندازی فروشنده (n صفحه) | 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 |
نسخه ۴
این پارتیشن از سرصفحه، بخش ramdisk فروشنده (شامل همه تکههای ramdisk فروشنده، بههم پیوسته)، blob درخت دستگاه (DTB)، و جدول ramdisk فروشنده تشکیل شده است.
| بخش | تعداد صفحهها |
|---|---|
| سرصفحه راهاندازی فروشنده (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 |
| جدول ramdisk فروشنده (q صفحه) | q = (vendor_ramdisk_table_size + page_size - 1) / page_size |
| Bootconfig (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_DLKMramdisk حاوی ماژولهای هسته بارشدنی پویا است.
ramdisk_nameنام منحصربهفرد دیسک مجازی است.-
board_idبرداری از شناسههای سختافزار تعریفشده توسط فروشنده است.
پشتیبانی از راهانداز سیستم
ازآنجاییکه پارتیشن بوت فروشنده حاوی اطلاعاتی (مانند اندازه صفحه حافظه فلش، هسته، نشانیهای بار ramdisk، خود DTB) است که قبلاً در پارتیشن بوت وجود داشت، بارگذار بوت باید به هر دو پارتیشن بوت و بوت فروشنده دسترسی داشته باشد تا دادههای کافی برای تکمیل بوت داشته باشد.
bootloader باید ramdisk عمومی را بلافاصله پساز ramdisk فروشنده در حافظه بار کند (قالبهای CPIO، Gzip، و lz4 از این نوع بههم پیوستن پشتیبانی میکنند). تصویر ramdisk عمومی را صفحهبندی نکنید یا هیچ فضای دیگری بین آن و انتهای ramdisk فروشنده در حافظه ایجاد نکنید. پساز اینکه هسته از حالت فشرده خارج شد، فایل بههمپیوسته را در یک initramfs استخراج میکند که منجر به ساختار فایلی میشود که یک دیسک مجازی عمومی است که روی ساختار فایل دیسک مجازی فروشنده قرار گرفته است.
ازآنجاییکه ramdisk عمومی و ramdisk فروشنده بههم متصل میشوند، باید در قالب یکسانی باشند. تصویر بوت GKI از ramdisk عمومی فشردهشده با lz4 استفاده میکند، بنابراین دستگاه سازگار با GKI باید از ramdisk فروشنده فشردهشده با lz4 استفاده کند. پیکربندی این مورد در زیر نشان داده شده است.
الزامات راهانداز سیستم برای پشتیبانی از bootconfig در پیادهسازی Bootconfig توضیح داده شده است.
چند دیسک مجازی فروشنده (نسخه ۴)
با نسخه ۴ سرصفحه تصویر راهاندازی، بوتلودر میتواند زیرمجموعهای از دیسکهای مجازی فروشنده یا همه آنها را برای بار کردن بهعنوان initramfs درطول زمان راهاندازی انتخاب کند. جدول ramdisk فروشنده حاوی فرادادههای هر ramdisk است و میتواند به
بارکننده در تصمیمگیری درباره اینکه کدام ramdiskها را بار کند کمک کند. بارکننده میتواند ترتیب بار کردن ramdiskهای فروشنده انتخابشده را تعیین کند، بهشرطی که ramdisk عمومی در آخر بار شود.
برای مثال، راهانداز سیستم میتواند از بار کردن دیسکهای مجازی فروشنده از نوع
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 هنگام بوت شدن در حالت بازیابی در حافظه بار میشوند.
یا، راهانداز سیستم میتواند جدول ramdisk فروشنده را نادیده بگیرد و کل بخش ramdisk فروشنده را بار کند. این کار همان تأثیری را دارد که بار کردن همه
تکههای ramdisk فروشنده در پارتیشن 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).
برای گنجاندن چند دیسک مجازی فروشنده در vendor_boot:
-
BOARD_BOOT_HEADER_VERSIONرا روی4تنظیم کنید.
BOARD_VENDOR_RAMDISK_FRAGMENTSرا روی فهرست نامهای قطعه ramdisk فروشنده منطقی تنظیم کنید تا درvendor_bootگنجانده شود.برای افزودن دیسک مجازی ازپیشساخته فروشنده،
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_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 تنظیم شده است.