מחיצה כללית להפעלה

ב-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, אין צורך בשינוי ב-recovery ramdisk כי הוא מכיל את כל מה שצריך.recovery

ארכיטקטורה

התרשימים הבאים מציגים את הארכיטקטורה של מכשירים עם Android 12 ואילך. מכשירים שמופעלת בהם מערכת Android 13 כוללים תמונה חדשה של init_boot שמכילה את ramdisk הגנרי. מכשירים שמשדרגים מ-Android 12 ל-Android 13 משתמשים באותה ארכיטקטורה כמו ב-Android 12.

הושק עם Android 13, ללא שחזור ייעודי

הפעלת המכשיר או שדרוג שלו, GKI, ללא שחזור ייעודי

איור 1. מכשירים שמופעלים או משודרגים ל-Android 13, עם GKI, ללא שחזור ייעודי.

השקה עם Android 13, שחזור ייעודי ושחזור A/B (דיסק RAM ייעודי)

הפעלת המכשיר או שדרוג שלו, GKI, שחזור ייעודי ושחזור A/B

איור 2. מכשירים שמופעלים עם Android 13 או משודרגים ל-Android 13, עם GKI, שחזור ייעודי ושחזור A/B.

אם במכשיר יש מחיצות recovery_a ו-recovery_b, אפשר להיעזר באיור הזה.

השקה עם Android 13, שחזור ייעודי ולא A/B (דיסק RAM ייעודי)

הפעלת המכשיר או שדרוג שלו, GKI, שחזור ייעודי ושחזור שהוא לא A/B

איור 3. מכשירים שמופעלים או משודרגים ל-Android 13, עם GKI, שחזור ייעודי ושחזור שאינו A/B.

אם למכשיר יש מחיצה בשם recovery ללא סיומת של משבצת, אפשר להיעזר באיור הזה.

השקה או שדרוג ל-Android 12, ללא שחזור ייעודי

הפעלת המכשיר או שדרוג שלו, GKI, ללא שחזור ייעודי

איור 4. מכשירים שהושקו עם Android 12 או שודרגו ל-Android 12, עם GKI, ללא שחזור ייעודי.

הפעלה או שדרוג ל-Android 12, שחזור ייעודי ושחזור A/B (דיסק RAM ייעודי)

הפעלת המכשיר או שדרוג שלו, GKI, שחזור ייעודי ושחזור A/B

איור 5. מכשירים שמופעלים עם Android 12 או משודרגים ל-Android 12, עם GKI, שחזור ייעודי ושחזור A/B.

אם במכשיר יש מחיצות recovery_a ו-recovery_b, אפשר להיעזר באיור הזה.

הפעלה או שדרוג ל-Android 12, שחזור ייעודי ולא A/B (דיסק RAM ייעודי)

הפעלת המכשיר או שדרוג שלו, GKI, שחזור ייעודי ושחזור שהוא לא A/B

איור 6. מכשירים שהושקו עם Android 12 או שודרגו ל-Android 12, עם GKI, שחזור ייעודי ושחזור שאינו A/B.

אם למכשיר יש מחיצה בשם recovery ללא סיומת של משבצת, אפשר להיעזר באיור הזה.

שדרוג ל-Android 12, שחזור כאתחול (שחזור כ-ramdisk)

הפעלת המכשיר או שדרוג שלו, ללא GKI, שחזור כהפעלה

איור 7. מכשירים שמשדרגים ל-Android 12, ללא GKI, שחזור כהפעלה.

שדרוג ל-Android 12, שחזור ייעודי (ramdisk ייעודי)

הפעלת המכשיר או שדרוג שלו, ללא GKI, שחזור ייעודי

איור 8. מכשירים שמשדרגים ל-Android 12, ללא GKI, שחזור ייעודי.

התוכן של קובצי אימג' לאתחול

תמונות האתחול של Android מכילות את הרכיבים הבאים.

  • נוספה תמונה של מכשירים עם Android 13init_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
  • vendor_boot תמונה (פרטים נוספים זמינים במאמר בנושא מחיצות של ספק)

    • vendor_boot header
      • מכשיר ספציפי cmdline (BOARD_KERNEL_CMDLINE)
    • vendor_boot ramdisk image
      • lib/modules
      • משאבי שחזור (אם אין שחזור ייעודי)
    • תמונה אחת (dtb)
  • תמונה אחת (recovery)

    • Header version V2
      • cmdline ספציפי למכשיר לשחזור, אם צריך
      • במחיצת שחזור שאינה A/B, התוכן של הכותרת צריך להיות עצמאי. אפשר לעיין בתמונות שחזור. לדוגמה:
      • הכתובת cmdline לא משורשרת לכתובות boot ו-vendor_boot cmdline.
      • אם צריך, הכותרת מציינת DTBO לשחזור.
      • במחיצת שחזור A/B, אפשר לשרשר את התוכן או להסיק אותו מ-boot ומ-vendor_boot. לדוגמה:
      • המחרוזת cmdline מורכבת מ-boot ו-vendor_boot cmdline.
      • אפשר להסיק את DTBO מהכותרת vendor_boot.
    • recovery ramdisk image
      • מקורות מידע לשחזור
      • במחיצת שחזור שאינה A/B, התוכן של ramdisk צריך להיות עצמאי. אפשר לעיין בתמונות שחזור. לדוגמה:
      • lib/modules חייב להכיל את כל מודולי הליבה שנדרשים כדי לאתחל את מצב השחזור
      • ה-ramdisk לשחזור חייב להכיל את init.
      • במחיצת השחזור A/B, ה-ramdisk של השחזור מתווסף לפני ה-ramdisk הכללי ו-vendor_boot, ולכן הוא לא צריך להיות עצמאי. לדוגמה:
      • lib/modules עשוי להכיל רק מודולים נוספים של ליבת המערכת שנדרשים כדי להפעיל את מצב השחזור, בנוסף למודולים של ליבת המערכת ב-ramdisk‏ vendor_boot.
      • יכול להיות שהקישור הסמלי ב-/init קיים, אבל הוא מוצל על ידי הקובץ הבינארי /init בשלב הראשון בקובץ אימג' לאתחול.

תוכן גנרי של תמונת ramdisk

ה-ramdisk הגנרי מכיל את הרכיבים הבאים.

  • init
  • system/etc/ramdisk/build.prop
  • ro.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/B recovery, צריך להגדיר את המשתנה הזה ל-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 ל-true, והארכיטקטורה תהיה כמו שמוצג באיור 3.

      • אם מגדירים את BOARD_USES_RECOVERY_AS_BOOT כריק, הארכיטקטורה תהיה כמו שמוצג באיור 4.

    • אפשר להגדיר את BOARD_USES_RECOVERY_AS_BOOT כריק. אם הם עושים זאת, הם משתמשים בהגדרות חדשות. אם המכשירים האלה:

      • אל תשתמשו במחיצה ייעודית recovery, הארכיטקטורה היא כמו שמוצג באיור 1 ואפשרות ההגדרה של המכשיר היא אפשרות 1.

      • משתמשים במחיצה ייעודית recovery, הארכיטקטורה היא כמו שמוצג באיור 2א או באיור 2ב, ואפשרות הגדרת המכשיר היא אפשרות 2א או אפשרות 2ב.

  • במכשירים שיושקו עם Android 12, צריך להגדיר את BOARD_USES_RECOVERY_AS_BOOT כריק ולהשתמש בהגדרות חדשות. אם המכשירים האלה:

    • לא משתמשים במחיצה ייעודית recovery, הארכיטקטורה היא כמו שמוצג באיור 1 ואפשרות הגדרת המכשיר היא אפשרות 1.

    • משתמשים במחיצה ייעודית recovery, הארכיטקטורה היא כמו שמוצג באיור 2א או באיור 2ב, ואפשרות הגדרת המכשיר היא אפשרות 2א או אפשרות 2ב.

מכיוון ש-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 (מ-recovery ramdisk, נוצר מ-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. תהליך האתחול של מצב השחזור הוא כזה:

  1. תוכנת האתחול מתחילה לפעול, ואז מתבצעות הפעולות הבאות:

    1. העברת שחזור + vendor_boot + ramdisk כללי אל /. (אם יצרן ה-OEM משכפל מודולים של ליבת המערכת ב-ramdisk של השחזור על ידי הוספתם אל BOARD_RECOVERY_KERNEL_MODULES, אז BOARD_RECOVERY_KERNEL_MODULES הוא אופציונלי).vendor_boot
    2. מפעילים את הליבה ממחיצת boot.
  2. הליבה מטמיעה את ramdisk ב-/ ואז מפעילה את /init מ-ramdisk כללי.

  3. השלב הראשון של האתחול מתחיל, ואז מתבצעות הפעולות הבאות:

    1. מגדיר את IsRecoveryMode() == true ואת ForceNormalBoot() == false.
    2. טוען מודולי ליבה של ספקים מ-/lib/modules.
    3. התקשרות אל DoFirstStageMount() אבל דילוג על ההתקנה כי IsRecoveryMode() == true. (המכשיר לא מפנה את ה-RAMDISK (כי / עדיין זהה), אבל הוא קורא ל-SetInitAvbVersionInRecovery()).
    4. מתחיל את שלב האתחול השני מ-/system/bin/init מ-recovery ramdisk.

הפיכת 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 (מ-recovery ramdisk)
  • /system/bin/init (מ-recovery ramdisk, נוצר מ-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. תהליך האתחול של מצב השחזור הוא כזה:

  1. תוכנת האתחול מתחילה לפעול, ואז מתבצעות הפעולות הבאות:

    1. העברת ramdisk לשחזור אל /.
    2. מפעילים את הליבה ממחיצת recovery.
  2. הליבה מטמיעה את ramdisk ב-/ ואז מפעילה את /init, שהוא קישור סמלי ל-/system/bin/init מ-ramdisk‏ recovery.

  3. השלב הראשון של האתחול מתחיל, ואז מתבצעות הפעולות הבאות:

    1. מגדיר את IsRecoveryMode() == true ואת ForceNormalBoot() == false.
    2. טוען מודולי ליבה של ספקים מ-/lib/modules.
    3. התקשרות אל DoFirstStageMount() אבל דילוג על ההתקנה כי IsRecoveryMode() == true. (המכשיר לא מפנה את ה-RAMDISK (כי / עדיין זהה), אבל הוא קורא ל-SetInitAvbVersionInRecovery()).
    4. מתחיל את שלב האתחול השני מ-/system/bin/init מ-recovery ramdisk.

חותמות זמן של קובץ אימג' לאתחול

הקוד הבא הוא דוגמה לקובץ חותמת זמן של תמונה 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.