اندروید 11 مفهوم تصویر هسته عمومی (GKI) را معرفی کرد. برای فعال کردن راهاندازی یک دستگاه دلخواه با GKI، دستگاههای Android 11 میتوانند از هدر تصویر بوت نسخه 3 استفاده کنند. در نسخه 3، تمام اطلاعات خاص فروشنده از پارتیشن boot
خارج میشوند و به پارتیشن vendor_boot
جدید منتقل میشوند. دستگاه ARM64 که با اندروید 11 روی هسته لینوکس 5.4 راه اندازی می شود، باید از پارتیشن vendor_boot
و فرمت پارتیشن boot
به روز شده پشتیبانی کند تا بتواند با GKI آزمایش کند.
دستگاههای Android 12 میتوانند از هدر تصویر بوت نسخه 4 استفاده کنند که از گنجاندن چندین ramdisk فروشنده در پارتیشن vendor_boot
پشتیبانی میکند. چند قطعه ramdisk فروشنده یکی پس از دیگری در بخش ramdisk فروشنده به هم متصل می شوند. یک جدول ramdisk فروشنده برای توصیف طرح بندی بخش ramdisk فروشنده و فراداده هر قطعه ramdisk فروشنده استفاده می شود.
ساختار پارتیشن
پارتیشن بوت فروشنده A/B-ed با A/B مجازی است و توسط Android Verified Boot محافظت می شود.
نسخه 3
این پارتیشن از یک هدر، ramdisk فروشنده و حباب درخت دستگاه (DTB) تشکیل شده است.
بخش | تعداد صفحات |
---|---|
هدر بوت فروشنده (n صفحه) | n = (2112 + page_size - 1) / page_size |
ramdisk فروشنده (o pages) | o = (vendor_ramdisk_size + page_size - 1) / page_size |
DTB (صفحه های ص) | p = (dtb_size + page_size - 1) / page_size |
نسخه 4
پارتیشن شامل یک سربرگ، بخش ramdisk فروشنده (شامل تمام قطعات ramdisk فروشنده، به هم پیوسته)، حباب درخت دستگاه (DTB) و جدول ramdisk فروشنده است.
بخش | تعداد صفحات |
---|---|
هدر بوت فروشنده (n صفحه) | n = (2128 + page_size - 1) / page_size |
قطعات ramdisk فروشنده (o pages) | 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) | 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 فروشنده است. -
ramdisk_type
نوع ramdisk را نشان می دهد، مقادیر ممکن عبارتند از:-
VENDOR_RAMDISK_TYPE_NONE
نشان می دهد که مقدار مشخص نشده است. - رام دیسک های
VENDOR_RAMDISK_TYPE_PLATFORM
حاوی بیت های خاص پلت فرم هستند. بوت لودر باید همیشه اینها را در حافظه بارگذاری کند. -
VENDOR_RAMDISK_TYPE_RECOVERY
ramdisk حاوی منابع بازیابی است. بوت لودر هنگام بوت شدن در ریکاوری باید اینها را در حافظه بارگذاری کند. - رمدیسک های
VENDOR_RAMDISK_TYPE_DLKM
حاوی ماژول های هسته قابل بارگیری پویا هستند.
-
-
ramdisk_name
نام منحصر به فرد ramdisk است. -
board_id
یک بردار از شناسه های سخت افزاری تعریف شده توسط فروشنده است.
پشتیبانی از بوت لودر
از آنجایی که پارتیشن بوت فروشنده حاوی اطلاعاتی است (مانند اندازه صفحه فلش، هسته، آدرس های بارگذاری ramdisk، خود DTB) که قبلاً در پارتیشن بوت وجود داشته است، بوت لودر باید به هر دو پارتیشن بوت و فروشنده دسترسی داشته باشد تا داده های کافی برای تکمیل بوت شدن داشته باشد. .
بوت لودر باید ramdisk عمومی را بلافاصله پس از ramdisk فروشنده در حافظه بارگذاری کند (فرمت های CPIO، Gzip و lz4 از این نوع الحاق پشتیبانی می کنند). تصویر ramdisk عمومی را صفحه تراز نکنید یا فضای دیگری بین آن و انتهای ramdisk فروشنده در حافظه معرفی نکنید. پس از اینکه هسته از حالت فشرده خارج شد، فایل الحاقی را به یک initramfs
استخراج میکند، که منجر به یک ساختار فایل میشود که یک ramdisk عمومی است که روی ساختار فایل ramdisk فروشنده قرار گرفته است.
از آنجایی که ramdisk عمومی و ramdisk فروشنده به هم متصل می شوند، باید در قالب یکسان باشند. تصویر بوت GKI از یک ramdisk عمومی فشرده شده با lz4 استفاده می کند، بنابراین دستگاهی که با GKI سازگار است باید از یک ramdisk فروشنده فشرده شده با lz4 استفاده کند. پیکربندی برای این در زیر نشان داده شده است.
الزامات بوت لودر برای پشتیبانی از bootconfig در Implement Bootconfig توضیح داده شده است.
رام دیسک چند فروشنده (نسخه 4)
با هدر تصویر بوت نسخه 4، بوت لودر می تواند یک زیرمجموعه یا همه رم دیسک های فروشنده را برای بارگذاری به عنوان 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
تنظیم کنید.BOARD_VENDOR_BOOTIMAGE_PARTITION_SIZE
را با توجه به ماژولهای هستهای که باید روی 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)
.
برای قرار دادن چندین 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 فروشنده خواهد بود. اولین مورد، ramdisk "پیشفرض" است که حاوی baz
دایرکتوری DLKM و بقیه فایلها در $(TARGET_VENDOR_RAMDISK_OUT)
است. مورد دوم ramdisk dlkm_foobar
است که شامل دایرکتوری های DLKM foo
و bar
است و --ramdisk_type
پیش فرض DLKM
است.