ב-Android 11 הושקה רעיון הליבה (kernel) הכללית
תמונה (GKI). כדי להפעיל אתחול של מכשיר שרירותי באמצעות GKI, Android
11 מכשירים יכולים להשתמש בגרסה 3 של כותרת תמונת האתחול. לחשבון
בגרסה 3, כל המידע הספציפי לספק נלקח מתוך boot
מחיצה והועברה למחיצה חדשה של vendor_boot
. מכשיר ARM64
ההשקה עם Android 11 בליבה (kernel) של Linux 5.4 חייבת
תומכים במחיצה vendor_boot
ובפורמט המחיצה המעודכן boot
כדי
לעבור את הבדיקות ב-GKI.
במכשירי Android 12 יכולים להשתמש בכותרת תמונת הפעלה בגרסה 4,
שתומך בהכללת מספר רדיסקים של ספקים בvendor_boot
מחיצה. מקטעי ramdisk של ספקים משורשרים אחד אחרי השני
בקטע ramdisk של הספק. טבלת ramdisk של ספק משמשת לתיאור
הפריסה של החלק ramdisk של הספק והמטא-נתונים של כל ramdisk של ספק
מקטע.
מבנה החלוקה
מחיצת האתחול של הספק היא A/B-ed באמצעות A/B וירטואלי ומוגנת על ידי Android הפעלה מאומתת.
גרסה 3
המחיצה מורכבת מכותרת, מ-ramdisk של הספק ומ-blob של עץ המכשיר (DTB).
קטע | מספר הדפים |
---|---|
כותרת האתחול של הספק (n דפים) | n = (2112 + page_size - 1) / page_size |
ramdisk של ספק (דפי O) | o = (vendor_ramdisk_size + page_size - 1) / page_size |
DTB (דפי p) | p = (dtb_size + page_size - 1) / page_size |
גרסה 4
המחיצה מורכבת מכותרת, הקטע ramdisk של הספק (כולל כל מקטעי ה-ramdisk של הספק, משורשרים), את ה-blob של עץ המכשיר (DTB) טבלת ramdisk של ספקים.
קטע | מספר הדפים |
---|---|
כותרת האתחול של הספק (n דפים) | n = (2128 + page_size - 1) / page_size |
קטעי ramdisk של ספק (דפי 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 |
Butconfig (דפי 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
מציין את סוג הרדיסק. הערכים האפשריים הם:VENDOR_RAMDISK_TYPE_NONE
מציין שהערך לא צוין.- קובצי ramdisk של
VENDOR_RAMDISK_TYPE_PLATFORM
מכילים ביטים ספציפיים לפלטפורמה. תוכנת האתחול חייבת תמיד לטעון אותן לזיכרון. VENDOR_RAMDISK_TYPE_RECOVERY
תיקיות ramdisk עם משאבי שחזור. תוכנת האתחול חייבת לטעון אותן לזיכרון במהלך ההפעלה במהלך השחזור.VENDOR_RAMDISK_TYPE_DLKM
RAMs מכילים ליבה (kernel) דינמית שניתן לטעון מודולים.
ramdisk_name
הוא שם ייחודי של הרדיסק.board_id
הוא וקטור של מזהי חומרה בהגדרת הספק.
תמיכה בתוכנת אתחול
מכיוון שמחיצת האתחול של הספק מכילה מידע (כגון גודל דף Flash, כתובות ליבה (kernel), לעומסי ramdisk, ה-DTB עצמו) שהיו קיימים בעבר מחיצת האתחול, תוכנת האתחול חייבת לגשת גם לאתחול וגם לאתחול של הספק למחיצות כך שיהיו מספיק נתונים להשלמת האתחול.
תוכנת האתחול חייבת לטעון את ה-ramdisk הגנרי לזיכרון באופן מיידי לאחר
ramdisk של הספק (הפורמטים CPIO, Gzip ו-lz4 תומכים בסוג כזה של
שרשור מחרוזות). אין ליישר דף לתמונה של ה-Radisk הגנרית או להוסיף
רווח אחר ביניהם לבין סוף ה-Radisk של הספק בזיכרון. אחרי
מבטל דחיסה של הליבה, הוא מחלץ את הקובץ המשורשר ל-initramfs
,
שהתוצאה שלו הוא מבנה קובץ שהוא רדיסק גנרי שמוצג כשכבת-על
את מבנה קובץ ramdisk של הספק.
מכיוון שה-ramdisk הגנרי ורדיסק הספק משורשרים, הם חייבים להיות אותו פורמט. תמונת האתחול של GKI משתמשת ברדיסק גנרי בדחיסת lz4, תואם ל-GKI חייב להשתמש ב-ramdisk של ספק בדחיסת lz4. בהגדרות האלה מוצגות בהמשך.
הדרישות של תוכנת האתחול לתמיכה בתצורת האתחול מוסברות בהסבר על יישום bootconfig.
ramdisk של ספקים מרובים (גרסה 4)
בגרסה 4 של כותרת תמונת האתחול, תוכנת האתחול יכולה לבחור קבוצת משנה או
את כל ה-ramdisks של הספקים שייטען כ-initramfs
במהלך זמן האתחול.
טבלת ramdisk של ספקים מכילה את המטא-נתונים של כל ramdisk, ויכולה לסייע
תוכנת אתחול שמחליטה אילו רדיסקים לטעון. תוכנת האתחול יכולה לקבוע
כדי לטעון את הרדיסקים של הספק שנבחר, כל עוד ה-Radisk הגנרי
נטען אחרונה.
לדוגמה, תוכנת האתחול יכולה להשמיט רדיסקים של ספק טעינה מסוג מסוים
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 של הספק ולטעון את
כל הקטע של ramdisk של הספק. הפעולה הזו משפיעה על הטעינה של כל
את מקטעי ה-ramdisk של הספק במחיצה vendor_boot
.
בניית תמיכה
כדי להטמיע תמיכה בהפעלה של הספק במכשיר:
צריך להגדיר את הערך של
BOARD_BOOT_HEADER_VERSION
לערך3
ומעלה.יש להגדיר את
BOARD_RAMDISK_USE_LZ4
לערךtrue
אם המכשיר תואם ל-GKI, או אם אחרת הוא משתמש לרדיסק גנרי בדחיסת lz4.הגדרת
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)
כדי לכלול רדיסקים של כמה ספקים ב-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
.
כדי ליצור משאבי שחזור כ-Radisk נפרד ב-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, שמכיל את ספריית DLKM baz
וגם
שאר הקבצים ב-$(TARGET_VENDOR_RAMDISK_OUT)
. השנייה היא
ramdisk dlkm_foobar
, שמכיל את ספריות ה-DLKM foo
ו-bar
, וגם
ברירת המחדל של --ramdisk_type
היא DLKM
.