ב-Android 12, תמונת boot הגנרית, שנקראת Generic Kernel Image (GKI), מכילה את ה-ramdisk הגנרי ואת ליבת ה-GKI.
במכשירים שמופעלת בהם Android 13, ה-ramdisk הגנרי מוסר מתמונת boot ומוצב בתמונת init_boot נפרדת. בעקבות השינוי הזה, תמונת boot תכלול רק את ליבת GKI.
לשדרוג מכשירים שממשיכים להשתמש ב-Android 12 או בגרסאות קודמות של ליבת המערכת, ה-ramdisk הגנרי נשאר במקומו ואין דרישה לתמונה חדשה של init_boot.
כדי ליצור ramdisk גנרי, צריך להעביר משאבים ספציפיים לספק מחוץ ל-ramdisk, כך שה-ramdisk הגנרי יכיל רק את השלב הראשון init וקובץ מאפיינים שמכיל מידע על חותמת זמן.
במכשירים שבהם:
לא משתמשים במחיצה ייעודית של
recovery, כל ביטי השחזור עוברים מ-ramdisk כללי ל-ramdisk שלvendor_boot.כן, צריך להשתמש במחיצה ייעודית
recovery, אין צורך בשינוי ב-recoveryramdisk כי הוא מכיל את כל מה שצריך.recovery
ארכיטקטורה
התרשימים הבאים מציגים את הארכיטקטורה של מכשירים עם Android 12 ואילך.
מכשירים שמופעלת בהם מערכת Android 13 כוללים תמונה חדשה של init_boot שמכילה את ramdisk הגנרי.
מכשירים שמשדרגים מ-Android 12 ל-Android 13 משתמשים באותה ארכיטקטורה כמו ב-Android 12.
הושק עם Android 13, ללא שחזור ייעודי
איור 1. מכשירים שמופעלים או משודרגים ל-Android 13, עם GKI, ללא שחזור ייעודי.
השקה עם Android 13, שחזור ייעודי ושחזור A/B (דיסק RAM ייעודי)
איור 2. מכשירים שמופעלים עם Android 13 או משודרגים ל-Android 13, עם GKI, שחזור ייעודי ושחזור A/B.
אם במכשיר יש מחיצות recovery_a ו-recovery_b, אפשר להיעזר באיור הזה.
השקה עם Android 13, שחזור ייעודי ולא A/B (דיסק RAM ייעודי)
איור 3. מכשירים שמופעלים או משודרגים ל-Android 13, עם GKI, שחזור ייעודי ושחזור שאינו A/B.
אם למכשיר יש מחיצה בשם recovery ללא סיומת של משבצת, אפשר להיעזר באיור הזה.
השקה או שדרוג ל-Android 12, ללא שחזור ייעודי
איור 4. מכשירים שהושקו עם Android 12 או שודרגו ל-Android 12, עם GKI, ללא שחזור ייעודי.
הפעלה או שדרוג ל-Android 12, שחזור ייעודי ושחזור A/B (דיסק RAM ייעודי)
איור 5. מכשירים שמופעלים עם Android 12 או משודרגים ל-Android 12, עם GKI, שחזור ייעודי ושחזור A/B.
אם במכשיר יש מחיצות recovery_a ו-recovery_b, אפשר להיעזר באיור הזה.
הפעלה או שדרוג ל-Android 12, שחזור ייעודי ולא A/B (דיסק RAM ייעודי)
איור 6. מכשירים שהושקו עם Android 12 או שודרגו ל-Android 12, עם GKI, שחזור ייעודי ושחזור שאינו A/B.
אם למכשיר יש מחיצה בשם recovery ללא סיומת של משבצת, אפשר להיעזר באיור הזה.
שדרוג ל-Android 12, שחזור כאתחול (שחזור כ-ramdisk)
איור 7. מכשירים שמשדרגים ל-Android 12, ללא GKI, שחזור כהפעלה.
שדרוג ל-Android 12, שחזור ייעודי (ramdisk ייעודי)
איור 8. מכשירים שמשדרגים ל-Android 12, ללא GKI, שחזור ייעודי.
התוכן של קובצי אימג' לאתחול
תמונות האתחול של Android מכילות את הרכיבים הבאים.
נוספה תמונה של מכשירים עם Android 13
init_boot- גרסת הכותרת V4
- תמונת ramdisk גנרית
תמונה גנרית (
boot)- גרסת הכותרת V3 או
V4
boot_signatureלאישור של קובץ אימג' לאתחול GKI (גרסה 4 בלבד). GKI מאומתboot.imgלא חתום להפעלה מאומתת. יצרני ציוד מקורי עדיין צריכים לחתום עלboot.imgשנוצר מראש באמצעות מפתח AVB שייחודי למכשיר.- גנרי (
cmdline)GENERIC_KERNEL_CMDLINE - ליבת GKI
- תמונת ramdisk גנרית
- הנתונים האלה נכללים רק בתמונות מ-Android 12 ומגרסאות קודמות
boot
- הנתונים האלה נכללים רק בתמונות מ-Android 12 ומגרסאות קודמות
- גרסת הכותרת V3 או
V4
vendor_bootתמונה (פרטים נוספים זמינים במאמר בנושא מחיצות של ספק)vendor_bootheader- מכשיר ספציפי
cmdline(BOARD_KERNEL_CMDLINE)
- מכשיר ספציפי
vendor_bootramdisk imagelib/modules- משאבי שחזור (אם אין שחזור ייעודי)
- תמונה אחת (
dtb)
תמונה אחת (
recovery)- Header version V2
cmdlineספציפי למכשיר לשחזור, אם צריך- במחיצת שחזור שאינה A/B, התוכן של הכותרת צריך להיות עצמאי. אפשר לעיין בתמונות שחזור. לדוגמה:
- הכתובת
cmdlineלא משורשרת לכתובותbootו-vendor_bootcmdline. - אם צריך, הכותרת מציינת DTBO לשחזור.
- במחיצת שחזור A/B, אפשר לשרשר את התוכן או להסיק אותו מ-
bootומ-vendor_boot. לדוגמה: - המחרוזת
cmdlineמורכבת מ-bootו-vendor_bootcmdline. - אפשר להסיק את DTBO מהכותרת
vendor_boot.
recoveryramdisk image- מקורות מידע לשחזור
- במחיצת שחזור שאינה A/B, התוכן של ramdisk צריך להיות עצמאי. אפשר לעיין בתמונות שחזור. לדוגמה:
-
lib/modulesחייב להכיל את כל מודולי הליבה שנדרשים כדי לאתחל את מצב השחזור - ה-ramdisk לשחזור חייב להכיל את
init. - במחיצת השחזור A/B, ה-ramdisk של השחזור מתווסף לפני ה-ramdisk הכללי ו-
vendor_boot, ולכן הוא לא צריך להיות עצמאי. לדוגמה: -
lib/modulesעשוי להכיל רק מודולים נוספים של ליבת המערכת שנדרשים כדי להפעיל את מצב השחזור, בנוסף למודולים של ליבת המערכת ב-ramdiskvendor_boot. - יכול להיות שהקישור הסמלי ב-
/initקיים, אבל הוא מוצל על ידי הקובץ הבינארי/initבשלב הראשון בקובץ אימג' לאתחול.
- Header version V2
תוכן גנרי של תמונת ramdisk
ה-ramdisk הגנרי מכיל את הרכיבים הבאים.
initsystem/etc/ramdisk/build.propro.PRODUCT.bootimg.* buildאביזרים- ספריות ריקות לנקודות ההרכבה:
debug_ramdisk/, mnt/, dev/, sys/,proc/, metadata/ first_stage_ramdisk/- ספריות ריקות כפולות לנקודות צירוף:
debug_ramdisk/, mnt/,dev/, sys/, proc/, metadata/
- ספריות ריקות כפולות לנקודות צירוף:
שילוב של קובץ אימג' לאתחול
דגלי build קובעים איך נוצרים תמונות של init_boot, boot, recovery ו-vendor_boot. הערך של משתנה בוליאני בלוח צריך להיות המחרוזת true או ריק (שזה ערך ברירת המחדל).
TARGET_NO_KERNEL. המשתנה הזה מציין אם הבנייה משתמשת בתמונת אתחול מוכנה מראש. אם המשתנה הזה מוגדר ל-true, צריך להגדיר אתBOARD_PREBUILT_BOOTIMAGEלמיקום של קובץ אימג' לאתחול המוכנה מראש (BOARD_PREBUILT_BOOTIMAGE:= device/${company}/${board}/boot.img)
BOARD_USES_RECOVERY_AS_BOOT. המשתנה הזה מציין אם המכשיר משתמש בתמונהrecoveryכתמונהboot. כשמשתמשים ב-GKI, המשתנה הזה ריק וצריך להעביר את משאבי השחזור אלvendor_boot.
BOARD_USES_GENERIC_KERNEL_IMAGE. המשתנה הזה מציין שהלוח משתמש ב-GKI. המשתנה הזה לא משפיע על sysprops או עלPRODUCT_PACKAGES.זהו מתג GKI ברמת הלוח. כל המשתנים הבאים מוגבלים על ידי המשתנה הזה.
BOARD_MOVE_RECOVERY_RESOURCES_TO_VENDOR_BOOT. המשתנה הזה קובע אם משאבי השחזור של ramdisk נוצרים ב-vendor_boot.אם המדיניות מוגדרת לערך
true, משאבי השחזור נוצרים רק ב-vendor-ramdisk/ולא ב-recovery/root/.אם השדה ריק, משאבי השחזור נוצרים רק ב-
recovery/root/ולא ב-vendor-ramdisk/.
BOARD_MOVE_GSI_AVB_KEYS_TO_VENDOR_BOOT. המשתנה הזה קובע אם מפתחות GSI AVB נוצרים ב-vendor_boot.אם ההגדרה היא
true, והתנאיBOARD_MOVE_RECOVERY_RESOURCES_TO_VENDOR_BOOTמתקיים:מוגדר, מפתחות GSI AVB בנויים ל-
$ANDROID_PRODUCT_OUT/vendor-ramdisk/first_stage_ramdisk/avb.לא מוגדר, מפתחות GSI AVB מובנים ל-
$ANDROID_PRODUCT_OUT/vendor-ramdisk/avb.
אם השדה ריק, אם
BOARD_RECOVERY_AS_ROOT:מוגדר, מפתחות GSI AVB בנויים ל-
$ANDROID_PRODUCT_OUT/recovery/root/first_stage_ramdisk/avb.לא מוגדר, מפתחות GSI AVB מובנים ל-
$ANDROID_PRODUCT_OUT/ramdisk/avb.
BOARD_EXCLUDE_KERNEL_FROM_RECOVERY_IMAGE. המשתנה הזה קובע אם התמונהrecoveryמכילה גרעין או לא. במכשירים עם Android מגרסה 12 ומעלה שמשתמשים במחיצת A/Brecovery, צריך להגדיר את המשתנה הזה ל-true. במכשירים עם Android 12 שמשתמשים במחיצות שאינן A/B, צריך להגדיר את המשתנה הזה לערךfalseכדי שקובץ אימג' לשחזור מערכת ההפעלה יהיה עצמאי.
BOARD_COPY_BOOT_IMAGE_TO_TARGET_FILES. המשתנה הזה קובע אם$OUT/boot*.imgמועתק אלIMAGES/בקבצי היעד.aosp_arm64צריך להגדיר את המשתנה הזה ל-true.במכשירים אחרים, המשתנה הזה צריך להיות ריק.
BOARD_INIT_BOOT_IMAGE_PARTITION_SIZE. המשתנה הזה קובע אם המשתנהinit_boot.imgנוצר ומגדיר את הגודל. כשההגדרה הזו מופעלת, ה-ramdisk הגנרי מתווסף אלinit_boot.imgבמקום אלboot.img, ונדרשת הגדרה של המשתניםBOARD_AVB_INIT_BOOT*כדי להשתמש ב-chained vbmeta.
שילובים מותרים
| רכיב או משתנה | שדרוג מכשיר ללא מחיצת שחזור | שדרוג מכשיר עם מחיצת שחזור | הפעלת המכשיר ללא מחיצת שחזור | הפעלת המכשיר עם מחיצת שחזור A/B | הפעלת המכשיר עם מחיצת שחזור שאינה A/B | aosp_arm64 |
|---|---|---|---|---|---|---|
מכיל boot |
כן | כן | כן | כן | כן | כן |
כולל את init_boot (Android 13) |
no | no | כן | כן | כן | כן |
מכיל vendor_boot |
אופציונלי | אופציונלי | כן | כן | כן | no |
מכיל recovery |
no | כן | no | כן | כן | no |
BOARD_USES_RECOVERY_AS_BOOT |
true |
ריק | ריק | ריק | ריק | ריק |
BOARD_USES_GENERIC_KERNEL_IMAGE |
ריק | ריק | true |
true |
true |
true |
PRODUCT_BUILD_RECOVERY_IMAGE |
ריק | true או ריק |
ריק | true או ריק |
true או ריק |
ריק |
BOARD_RECOVERYIMAGE_PARTITION_SIZE |
ריק | > 0 | ריק | > 0 | > 0 | ריק |
BOARD_MOVE_RECOVERY_RESOURCES_TO_VENDOR_BOOT |
ריק | ריק | true |
ריק | ריק | ריק |
BOARD_MOVE_GSI_AVB_KEYS_TO_VENDOR_BOOT |
ריק | ריק | true |
true |
true |
ריק |
BOARD_EXCLUDE_KERNEL_FROM_RECOVERY_IMAGE |
ריק | ריק | ריק | true |
ריק | ריק |
BOARD_COPY_BOOT_IMAGE_TO_TARGET_FILES |
ריק | ריק | ריק | ריק | ריק | true |
במכשירים עם מחיצה ייעודית של recovery, אפשר להגדיר את PRODUCT_BUILD_RECOVERY_IMAGE לערך true או לערך ריק. במכשירים האלה, אם מוגדר BOARD_RECOVERYIMAGE_PARTITION_SIZE, נוצרת תמונה של recovery.
הפעלת vbmeta בשרשרת לצורך אתחול
צריך להפעיל שרשור של קובצי vbmeta לתמונות boot ו-init_boot. מציינים את הפרטים הבאים:
BOARD_AVB_BOOT_KEY_PATH := external/avb/test/data/testkey_rsa4096.pem
BOARD_AVB_BOOT_ALGORITHM := SHA256_RSA4096
BOARD_AVB_BOOT_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP)
BOARD_AVB_BOOT_ROLLBACK_INDEX_LOCATION := 2
BOARD_AVB_INIT_BOOT_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem
BOARD_AVB_INIT_BOOT_ALGORITHM := SHA256_RSA2048
BOARD_AVB_INIT_BOOT_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP)
BOARD_AVB_INIT_BOOT_ROLLBACK_INDEX_LOCATION := 3
לדוגמה, אפשר לעיין בשינוי הזה.
System-as-root
מערכת כשורש לא נתמכת במכשירים שמשתמשים ב-GKI. במכשירים כאלה, השדה BOARD_BUILD_SYSTEM_ROOT_IMAGE צריך להיות ריק. מערכת כבסיס (System-as-root) לא נתמכת גם במכשירים שמשתמשים במחיצות דינמיות.
הגדרות מוצר
במכשירים שמשתמשים ב-ramdisk כללי, צריך להתקין רשימה של קבצים שמותר להתקין ב-ramdisk. כדי לעשות זאת, מציינים את הפרטים הבאים ב-device.mk:
$(call inherit-product, $(SRC_TARGET_DIR)/product/generic_ramdisk.mk)
הקובץ generic_ramdisk.mk גם מונע מקובצי makefile אחרים להתקין בטעות קבצים אחרים ב-ramdisk (צריך להעביר קבצים כאלה אל vendor_ramdisk במקום).
הגדרת מכשירים
הוראות ההגדרה שונות במכשירים עם Android 13, במכשירים שמשדרגים ל-Android 12 ובמכשירים עם Android 12. Android 13, ההגדרה דומה להגדרה ב-Android 12
מכשירים שמשדרגים ל-Android 12:
אפשר לשמור את הערך של
BOARD_USES_RECOVERY_AS_BOOT. אם הם עושים את זה, הם משתמשים בהגדרות מדור קודם, והמשתנים החדשים של הגדרות ה-build צריכים להיות ריקים. אם המכשירים האלה:אפשר להגדיר את
BOARD_USES_RECOVERY_AS_BOOTכריק. אם הם עושים זאת, הם משתמשים בהגדרות חדשות. אם המכשירים האלה:
במכשירים שיושקו עם Android 12, צריך להגדיר את
BOARD_USES_RECOVERY_AS_BOOTכריק ולהשתמש בהגדרות חדשות. אם המכשירים האלה:
מכיוון ש-aosp_arm64 בונה רק GKI (ולא vendor_boot או שחזור), הוא לא יעד מלא. למידע על aosp_arm64הגדרות של גרסאות build, אפשר לעיין במאמר generic_arm64.
אפשרות 1: אין מחיצת שחזור ייעודית
במכשירים ללא מחיצת recovery, התמונה הגנרית boot נמצאת במחיצת boot. ה-vendor_boot ramdisk מכיל את כל משאבי השחזור, כולל lib/modules (עם מודולים של ליבת הספק). במכשירים כאלה, הגדרות המוצר עוברות בירושה מ-generic_ramdisk.mk.
הגדרת ערכים של לוח
מגדירים את הערכים הבאים:
BOARD_USES_RECOVERY_AS_BOOT :=
BOARD_USES_GENERIC_KERNEL_IMAGE := true
BOARD_MOVE_RECOVERY_RESOURCES_TO_VENDOR_BOOT := true
BOARD_EXCLUDE_KERNEL_FROM_RECOVERY_IMAGE :=
BOARD_MOVE_GSI_AVB_KEYS_TO_VENDOR_BOOT := true
הפעלת קובצי הפעלה וקישורי סמלים
ה-ramdisk vendor_boot יכול להכיל קישור סמלי /init אל /system/bin/init, ו-init_second_stage.recovery ב-/system/bin/init. עם זאת, מכיוון ש-ramdisk גנרי מורכב אחרי ramdisk vendor_boot, הקישור הסמלי /init נכתב מחדש. כשהמכשיר מבצע אתחול למצב שחזור, נדרש קובץ הבינארי /system/bin/init כדי לתמוך באתחול בשלב השני. התוכן של vendor_boot + generic ramdisks הוא כדלקמן:
-
/init(מ-generic ramdisk, נוצר מ-init_first_stage) -
/system/bin/init(מ-vendor_ramdisk, נוצר מ-init_second_stage.recovery)
העברת קובצי fstab
מעבירים את כל הקבצים fstab שהותקנו ל-ramdisk הכללי אל vendor_ramdisk. לדוגמה, אפשר לעיין בשינוי הזה.
התקנת מודולים
אפשר להתקין מודולים ספציפיים למכשיר vendor_ramdisk (אם אין לכם מודולים ספציפיים למכשיר להתקנה, אפשר לדלג על השלב הזה).
משתמשים בגרסת
vendor_ramdiskשל המודול כשהמודול מותקן ב-/first_stage_ramdisk. המודול הזה אמור להיות זמין אחרי ש-initמעביר את השורש אל/first_stage_ramdisk, אבל לפני ש-initמעביר את השורש אל/system. דוגמאות אפשר לראות במאמרים סכומי ביקורת של מטא-נתונים ודחיסה וירטואלית של בדיקות A/B.משתמשים בווריאציה
recoveryשל המודול כשהמודול מותקן ב-/. המודול הזה צריך להיות זמין לפני ש-initמעביר את שורש המערכת אל/first_stage_ramdisk. פרטים על התקנת מודולים ב-/זמינים במאמר מסוף השלב הראשון.
מסוף השלב הראשון
מכיוון שהמסוף בשלב הראשון מתחיל לפני ש-init מעביר את השורש אל /first_stage_ramdisk, צריך להתקין את גרסת המודולים recovery.
כברירת מחדל, שני סוגי המודולים מותקנים בתיקייה build/make/target/product/base_vendor.mk, כך שאם קובץ ה-Makefile של המכשיר עובר בירושה מהקובץ הזה, לא צריך להתקין במפורש את סוג המודול recovery.
כדי להתקין במפורש את מודולי השחזור, משתמשים בפקודה הבאה.
PRODUCT_PACKAGES += \
linker.recovery \
shell_and_utilities_recovery \
כך מוודאים שהאפליקציות linker, sh ו-toybox יותקנו ב-$ANDROID_PRODUCT_OUT/recovery/root/system/bin, שמותקן ב-/system/bin בקטע vendor_ramdisk.
כדי להוסיף מודולים שנדרשים למסוף בשלב הראשון (לדוגמה, adbd), משתמשים בפקודה הבאה.
PRODUCT_PACKAGES += adbd.recovery
כך מוודאים שהמודולים שצוינו מותקנים בנתיב $ANDROID_PRODUCT_OUT/recovery/root/system/bin, שמותקן בנתיב /system/bin מתחת ל-vendor_ramdisk.
סיכומי ביקורת של מטא-נתונים
כדי לתמוך בסכומי ביקורת של מטא-נתונים במהלך ההרכבה בשלב הראשון, מכשירים שלא תומכים ב-GKI מתקינים את הגרסה של ramdisk של המודולים הבאים. כדי להוסיף תמיכה ב-GKI, מעבירים את המודולים אל
$ANDROID_PRODUCT_OUT/vendor-ramdisk/first_stage_ramdisk/system/bin:
PRODUCT_PACKAGES += \
linker.vendor_ramdisk \
resize2fs.vendor_ramdisk \
tune2fs.vendor_ramdisk \
דוגמה אפשר לראות ברשימת השינויים הזו.
דחיסה וירטואלית של A/B
כדי לתמוך בדחיסת A/B וירטואלית, צריך להתקין את snapuserd ב-vendor_ramdisk. המכשיר צריך לקבל בירושה מ-virtual_ab_ota/compression.mk את הווריאנט vendor_ramdisk של snapuserd.
שינויים בתהליך האתחול
תהליך האתחול למצב שחזור או ל-Android לא משתנה, למעט המקרים הבאים:
- Ramdisk
build.propעובר אל/second_stage_resourcesכדי שהשלב השניinitיוכל לקרוא את חותמת הזמן של האתחול.
הסיבה לכך היא שהמשאבים עוברים מ-ramdisk גנרי ל-ramdisk של vendor_boot, ולכן התוצאה של שרשור ramdisk גנרי ל-ramdisk של vendor_boot לא משתנה.
הפיכת e2fsck לזמין
קבצי ה-Makefile של המכשיר יכולים לרשת מ:
virtual_ab_ota/launch_with_vendor_ramdisk.mkאם המכשיר תומך ב-A/B וירטואלי אבל לא בדחיסה.
virtual_ab_ota/compression.mkאם המכשיר תומך בדחיסה וירטואלית של A/B.
קבצי ה-Makefile של המוצר מתקינים את $ANDROID_PRODUCT_OUT/vendor-ramdisk/first_stage_ramdisk/system/bin/e2fsck. בזמן הריצה, השלב הראשון init מעביר את השורש אל /first_stage_ramdisk ואז מפעיל את /system/bin/e2fsck.
אפשרות 2א: מחיצת שחזור ייעודית ומחיצת שחזור של בדיקות A/B
משתמשים באפשרות הזו במכשירים עם מחיצות A/B recovery, כלומר, במכשיר יש recovery_a ו-recovery_b partition. מכשירים כאלה כוללים מכשירי A/B ומכשירי Virtual A/B שניתן לעדכן את מחיצת השחזור שלהם, עם ההגדרה הבאה:
AB_OTA_PARTITIONS += recovery
vendor_boot ramdisk מכיל את חלקי הספק של ramdisk ומודולים של ליבת הספק, כולל:
קבצים ספציפיים ל-
fstab
lib/modules(כולל מודולים של ליבת הספק)
recovery ה-ramdisk מכיל את כל משאבי השחזור. במכשירים כאלה, הגדרות המוצר עוברות בירושה מ-generic_ramdisk.mk.
הגדרת ערכים של לוח
מגדירים את הערכים הבאים למכשירים עם מחיצת A/B recovery:
BOARD_USES_RECOVERY_AS_BOOT :=
BOARD_USES_GENERIC_KERNEL_IMAGE := true
BOARD_MOVE_RECOVERY_RESOURCES_TO_VENDOR_BOOT :=
BOARD_EXCLUDE_KERNEL_FROM_RECOVERY_IMAGE := true
BOARD_MOVE_GSI_AVB_KEYS_TO_VENDOR_BOOT := true
הפעלת קובצי הפעלה וקישורי סמלים
ה-recovery ramdisk יכול להכיל /init -> /system/bin/init symlink, ו-
init_second_stage.recovery ב-/system/bin/init. עם זאת, מכיוון ש-ramdisk של האתחול מחובר אחרי ramdisk של recovery, הקישור הסמלי /init נכתב מחדש. כשהמכשיר נטען למצב שחזור, נדרש קובץ /system/bin/init
בינארי כדי לתמוך בשלב השני של ההפעלה.
כשהמכשיר מבצע אתחול ל-recovery, התוכן של recovery +
vendor_boot + דיסקי ה-RAM הגנריים הוא כדלקמן:
-
/init(מ-ramdisk, נוצר מ-init_first_stage) -
/system/bin/init(מ-recoveryramdisk, נוצר מ-init_second_stage.recovery, והופעל מ-/init)
כשהמכשיר מפעיל את Android, התוכן של vendor_boot + generic
ramdisks הוא כדלקמן:
-
/init(מ-generic ramdisk, נוצר מ-init_first_stage)
העברת קובצי fstab
מעבירים את כל הקבצים fstab שהותקנו ב-ramdisk הכללי אל vendor_ramdisk. לדוגמה, אפשר לעיין בשינוי הזה.
התקנת מודולים
אפשר גם להתקין מודולים ספציפיים למכשיר vendor_ramdisk (אם אין לכם מודולים ספציפיים למכשיר להתקנה, אפשר לדלג על השלב הזה). Init
לא מתבצעת החלפה של שורש. הווריאציה vendor_ramdisk של המודולים מותקנת בתיקיית הבסיס של vendor_ramdisk. דוגמאות להתקנת מודולים ב-vendor_ramdisk מופיעות במאמרים מסוף השלב הראשון, סיכומי ביקורת של מטא-נתונים ודחיסה של בדיקות A/B וירטואליות.
מסוף השלב הראשון
כדי להתקין את הגרסה vendor_ramdisk של המודולים, משתמשים בפקודה הבאה:
PRODUCT_PACKAGES += \
linker.vendor_ramdisk \
shell_and_utilities_vendor_ramdisk \
כך מוודאים שהאפליקציות linker, sh ו-toybox יותקנו ב-$ANDROID_PRODUCT_OUT/vendor-ramdisk/system/bin, שמותקן ב-/system/bin בקטע vendor_ramdisk.
כדי להוסיף מודולים שנדרשים למסוף בשלב הראשון (לדוגמה, adbd), צריך להפעיל את וריאנט vendor_ramdisk של המודולים האלה על ידי העלאת תיקונים רלוונטיים ל-AOSP, ואז להשתמש בפקודה הבאה:
PRODUCT_PACKAGES += adbd.vendor_ramdisk
כך מוודאים שהמודולים שצוינו יותקנו בנתיב $ANDROID_PRODUCT_OUT/vendor-ramdisk/system/bin. אם vendor_boot ramdisk
נטען במצב שחזור, המודול זמין גם ב-recovery. אם קובץ ה-ramdisk vendor_boot לא נטען במצב שחזור, המכשיר יכול גם להתקין את adbd.recovery.
סיכומי ביקורת של מטא-נתונים
כדי לתמוך בסכומי ביקורת של מטא-נתונים במהלך ההרכבה בשלב הראשון, מכשירים שלא תומכים ב-GKI מתקינים את הגרסה של ramdisk של המודולים הבאים. כדי להוסיף תמיכה ב-GKI, מעבירים את המודולים אל
$ANDROID_PRODUCT_OUT/vendor-ramdisk/system/bin:
PRODUCT_PACKAGES += \
linker.vendor_ramdisk \
resize2fs.vendor_ramdisk \
tune2fs.vendor_ramdisk \
דוגמה אפשר לראות ברשימת השינויים הזו.
דחיסה וירטואלית של A/B
כדי לתמוך בדחיסת בדיקות A/B וירטואליות, צריך להתקין את snapuserd ב-vendor_ramdisk. המכשיר צריך לקבל בירושה מ-virtual_ab_ota/compression.mk את הווריאנט vendor_ramdisk של snapuserd.
שינויים בתהליך האתחול
תהליך האתחול לא משתנה כשמבצעים אתחול ל-Android. ה-vendor_boot +
generic ramdisk דומה לתהליך האתחול הקיים, רק ש-fstab
נטען מ-vendor_boot. מכיוון שהקובץ system/bin/recovery לא קיים, המערכת של first_stage_init מטפלת בזה כאילו מדובר באתחול רגיל.
כשמבצעים אתחול למצב שחזור, תהליך האתחול משתנה. השחזור + vendor_boot + generic ramdisk דומה לתהליך השחזור הקיים, אבל הליבה נטענת מהתמונה boot במקום מהתמונה recovery.
תהליך האתחול של מצב השחזור הוא כזה:
תוכנת האתחול מתחילה לפעול, ואז מתבצעות הפעולות הבאות:
- העברת שחזור +
vendor_boot+ ramdisk כללי אל/. (אם יצרן ה-OEM משכפל מודולים של ליבת המערכת ב-ramdisk של השחזור על ידי הוספתם אלBOARD_RECOVERY_KERNEL_MODULES, אזBOARD_RECOVERY_KERNEL_MODULESהוא אופציונלי).vendor_boot - מפעילים את הליבה ממחיצת
boot.
- העברת שחזור +
הליבה מטמיעה את ramdisk ב-
/ואז מפעילה את/initמ-ramdisk כללי.השלב הראשון של האתחול מתחיל, ואז מתבצעות הפעולות הבאות:
- מגדיר את
IsRecoveryMode() == trueואתForceNormalBoot() == false. - טוען מודולי ליבה של ספקים מ-
/lib/modules. - התקשרות אל
DoFirstStageMount()אבל דילוג על ההתקנה כיIsRecoveryMode() == true. (המכשיר לא מפנה את ה-RAMDISK (כי/עדיין זהה), אבל הוא קורא ל-SetInitAvbVersionInRecovery()). - מתחיל את שלב האתחול השני מ-
/system/bin/initמ-recoveryramdisk.
- מגדיר את
הפיכת e2fsck לזמין
קבצי ה-Makefile של המכשיר יכולים לרשת מ:
virtual_ab_ota/launch_with_vendor_ramdisk.mkאם המכשיר תומך ב-A/B וירטואלי אבל לא בדחיסה.
virtual_ab_ota/compression.mkאם המכשיר תומך בדחיסה וירטואלית של A/B.
קבצי ה-Makefile של המוצר מתקינים את $ANDROID_PRODUCT_OUT/vendor-ramdisk/system/bin/e2fsck. בזמן הריצה, השלב הראשון init מופעל /system/bin/e2fsck.
אפשרות 2ב: מחיצת שחזור ייעודית שאינה A/B
משתמשים באפשרות הזו למכשירים עם מחיצה מסוג recovery שאינה A/B, כלומר, למכשיר יש מחיצה בשם recovery ללא סיומת משבצת. מכשירים כאלה כוללים:
- מכשירים מסוג A/B;
- מכשירי A/B ומכשירי Virtual A/B, שאי אפשר לעדכן את מחיצת השחזור שלהם. (זה לא רגיל).
vendor_boot ramdisk מכיל את חלקי הספק של ramdisk ומודולים של ליבת הספק, כולל:
- קבצים ספציפיים ל-
fstab -
lib/modules(כולל מודולים של ליבת הספק)
recovery התמונה צריכה להיות עצמאית. הוא צריך להכיל את כל המשאבים הנדרשים להפעלת מצב השחזור, כולל:
- קובץ האימג' של הליבה
- קובץ האימג' של DTBO
- מודולים של ליבה ב-
lib/modules - הפעלה בשלב הראשון כקישור סמלי
/init -> /system/bin/init - קובץ בינארי של הפעלה ראשונית בשלב השני
/system/bin/init - קבצים ספציפיים ל-
fstab - כל שאר משאבי השחזור, כולל
recoveryקובץ בינארי
במכשירים כאלה, הגדרת המוצר מועברת מ-generic_ramdisk.mk.
הגדרת ערכים של לוח
מגדירים את הערכים הבאים למכשירים שלא תומכים בבדיקות A/B:
BOARD_USES_RECOVERY_AS_BOOT :=
BOARD_USES_GENERIC_KERNEL_IMAGE := true
BOARD_MOVE_RECOVERY_RESOURCES_TO_VENDOR_BOOT :=
BOARD_EXCLUDE_KERNEL_FROM_RECOVERY_IMAGE :=
BOARD_MOVE_GSI_AVB_KEYS_TO_VENDOR_BOOT := true
הפעלת קובצי הפעלה וקישורי סמלים
ה-ramdisk recovery חייב להכיל קישור סמלי /init -> /system/bin/init ו-init_second_stage.recovery ב-/system/bin/init. כשמפעילים את המכשיר במצב שחזור, צריך את הקובץ הבינארי /system/bin/init כדי לתמוך באתחול בשלב הראשון ובשלב השני.
כשהמכשיר מבצע אתחול ל-recovery, התוכן של דיסקי ה-RAM של recovery הוא כדלקמן:
/init -> /system/bin/init(מ-recoveryramdisk)-
/system/bin/init(מ-recoveryramdisk, נוצר מ-init_second_stage.recovery, והופעל מ-/init)
כשהמכשיר מפעיל את Android, התוכן של vendor_boot + generic
ramdisks הוא כדלקמן:
-
/init(מ-ramdisk, נוצר מ-init_first_stage)
העברת קובצי fstab
מעבירים את כל הקבצים fstab שהותקנו ל-ramdisk הכללי אל vendor_ramdisk ו-recovery ramdisk. לדוגמה, אפשר לעיין בשינוי הזה.
התקנת מודולים
אפשר להתקין מודולים ספציפיים למכשיר ב-vendor_ramdisk וב-recovery ramdisk (מדלגים על השלב הזה אם אין מודולים ספציפיים למכשיר להתקנה). init
לא מתבצעת החלפה של שורש. הווריאציה vendor_ramdisk של המודולים מותקנת בתיקיית הבסיס של vendor_ramdisk. הווריאנט recovery של המודולים מותקן בבסיס של recovery ramdisk. דוגמאות להתקנת מודולים ב-vendor_ramdisk וב-recovery ramdisk מופיעות במאמרים מסוף השלב הראשון וסיכומי ביקורת של מטא-נתונים.
מסוף השלב הראשון
כדי להתקין את הגרסה vendor_ramdisk של המודולים, משתמשים בפקודה הבאה:
PRODUCT_PACKAGES += \
linker.vendor_ramdisk \
shell_and_utilities_vendor_ramdisk \
כך מוודאים שהאפליקציות linker, sh ו-toybox יותקנו ב-$ANDROID_PRODUCT_OUT/vendor-ramdisk/system/bin, שמותקן ב-/system/bin בקטע vendor_ramdisk.
כדי להוסיף מודולים שנדרשים למסוף בשלב הראשון (לדוגמה, adbd), צריך להפעיל את וריאנט vendor_ramdisk של המודולים האלה על ידי העלאת תיקונים רלוונטיים ל-AOSP, ואז להשתמש בפקודה הבאה:
PRODUCT_PACKAGES += adbd.vendor_ramdisk
כך מוודאים שהמודולים שצוינו יותקנו בנתיב $ANDROID_PRODUCT_OUT/vendor-ramdisk/system/bin.
כדי להתקין את הווריאציה recovery של המודולים, מחליפים את vendor_ramdisk ב-recovery:
PRODUCT_PACKAGES += \
linker.recovery \
shell_and_utilities_recovery \
adbd.recovery \
סיכומי ביקורת של מטא-נתונים
כדי לתמוך בסכומי ביקורת של מטא-נתונים במהלך ההרכבה בשלב הראשון, מכשירים שלא תומכים ב-GKI מתקינים את הגרסה של ramdisk של המודולים הבאים. כדי להוסיף תמיכה ב-GKI, מעבירים את המודולים אל
$ANDROID_PRODUCT_OUT/vendor-ramdisk/system/bin:
PRODUCT_PACKAGES += \
linker.vendor_ramdisk \
resize2fs.vendor_ramdisk \
tune2fs.vendor_ramdisk \
כדי לתמוך בסכומי ביקורת של מטא-נתונים במהלך ההרכבה בשלב הראשון בשחזור, צריך להפעיל את וריאציית השחזור של המודולים האלה ולהתקין אותם גם כן.
שינויים בתהליך האתחול
תהליך האתחול לא משתנה כשמבצעים אתחול ל-Android. ה-vendor_boot +
generic ramdisk דומה לתהליך האתחול הקיים, רק ש-fstab
נטען מ-vendor_boot. מכיוון שהקובץ system/bin/recovery לא קיים, המערכת של first_stage_init מטפלת בזה כאילו מדובר באתחול רגיל.
כשמפעילים את המכשיר במצב שחזור, תהליך ההפעלה לא משתנה. ה-ramdisk של השחזור נטען באותו אופן כמו בתהליך השחזור הקיים.
הליבה נטענת מקובץ האימג' recovery. תהליך האתחול של מצב השחזור הוא כזה:
תוכנת האתחול מתחילה לפעול, ואז מתבצעות הפעולות הבאות:
- העברת ramdisk לשחזור אל
/. - מפעילים את הליבה ממחיצת
recovery.
- העברת ramdisk לשחזור אל
הליבה מטמיעה את ramdisk ב-
/ואז מפעילה את/init, שהוא קישור סמלי ל-/system/bin/initמ-ramdiskrecovery.השלב הראשון של האתחול מתחיל, ואז מתבצעות הפעולות הבאות:
- מגדיר את
IsRecoveryMode() == trueואתForceNormalBoot() == false. - טוען מודולי ליבה של ספקים מ-
/lib/modules. - התקשרות אל
DoFirstStageMount()אבל דילוג על ההתקנה כיIsRecoveryMode() == true. (המכשיר לא מפנה את ה-RAMDISK (כי/עדיין זהה), אבל הוא קורא ל-SetInitAvbVersionInRecovery()). - מתחיל את שלב האתחול השני מ-
/system/bin/initמ-recoveryramdisk.
- מגדיר את
חותמות זמן של קובץ אימג' לאתחול
הקוד הבא הוא דוגמה לקובץ חותמת זמן של תמונה boot:
####################################
# from generate-common-build-props
# These properties identify this partition image.
####################################
ro.product.bootimage.brand=Android
ro.product.bootimage.device=generic_arm64
ro.product.bootimage.manufacturer=unknown
ro.product.bootimage.model=AOSP on ARM64
ro.product.bootimage.name=aosp_arm64
ro.bootimage.build.date=Mon Nov 16 22:46:27 UTC 2020
ro.bootimage.build.date.utc=1605566787
ro.bootimage.build.fingerprint=Android/aosp_arm64/generic_arm64:S/MASTER/6976199:userdebug/test-keys
ro.bootimage.build.id=MASTER
ro.bootimage.build.tags=test-keys
ro.bootimage.build.type=userdebug
ro.bootimage.build.version.incremental=6976199
ro.bootimage.build.version.release=11
ro.bootimage.build.version.release_or_codename=S
ro.bootimage.build.version.sdk=30
# Auto-added by post_process_props.py
persist.sys.usb.config=none
# end of file
בזמן הבנייה, קובץ
system/etc/ramdisk/build.propמתווסף ל-ramdisk הכללי. הקובץ הזה מכיל מידע על חותמות הזמן של ה-build.בזמן הריצה, בשלב הראשון
initמועתקים קבצים מ-ramdisk אלtmpfsלפני ש-ramdisk משוחרר, כדי שבשלב השניinitתהיה אפשרות לקרוא את הקובץ הזה כדי להגדיר מאפיינים של חותמת זמן של תמונתboot.