יישום עדכוני A / B

יצרני OEM SoC ספקים שרוצים ליישם עדכוני מערכת A / B חייבים להבטיח סככת מנהל האתחול שלהם boot_control HAL ומעבירים את הפרמטרים הנכונים אלי הליבה.

יישום בקרת האתחול HAL

A / B-מסוגל bootloaders חייב ליישם את boot_control HAL על hardware/libhardware/include/hardware/boot_control.h . אתה יכול לבדוק יישומים באמצעות system/extras/bootctl שירות system/extras/tests/bootloader/ .

עליך גם ליישם את מכונת המדינה המוצגת להלן:

מכונת המדינה איור 1. Bootloader

הגדרת הגרעין

ליישום עדכוני מערכת A/B:

  1. Cherrypick את סדרת תיקוני הגרעין הבאה (במידת הצורך):
  2. ודא טיעונים שורת הפקודה הקרנל להכיל את הטיעונים הנוספים הבאים:
    skip_initramfs rootwait ro init=/init root="/dev/dm-0 dm=system none ro,0 1 android-verity <public-key-id> <path-to-system-partition>"
    ... איפה <public-key-id> ערך הוא מזהה את המפתח הציבורי המשמש לאמת את החתימה שולחן וריטי (לפרטים, ראה dm-אמתה ) .
  3. הוסף את אישור .X509 המכיל את המפתח הציבורי למפתח המפתח של המערכת:
    1. העתק את האישור .X509 מעוצב בתוך .der בפורמט לשורש של kernel בספרייה. אם האישור .X509 מעוצב כמו .pem קובץ, השתמש בנוסחה הבאה openssl הפקודה כדי להמיר מ .pem כדי .der פורמט:
      openssl x509 -in <x509-pem-certificate> -outform der -out <x509-der-certificate>
    2. בנה את zImage לכלול את תעודת כחלק סיסמאות המערכת. כדי לוודא, לבדוק את procfs הכניסה (דורש KEYS_CONFIG_DEBUG_PROC_KEYS צריכה להיות מופעלים):
      angler:/# cat /proc/keys
      
      1c8a217e I------     1 perm 1f010000     0     0 asymmetri
      Android: 7e4333f9bba00adfe0ede979e28ed1920492b40f: X509.RSA 0492b40f []
      2d454e3e I------     1 perm 1f030000     0     0 keyring
      .system_keyring: 1/4
      לשילוב מוצלח של התעודה .X509 מעיד על קיומו של המפתח הציבורי מחזיק מפתחות מערכת (שיא מציין את מזהה המפתח הציבורי).
    3. החלף את החלל עם # ולהעביר אותו כמו <public-key-id> בשורת הפקודה kernel. לדוגמה, לעבור Android:#7e4333f9bba00adfe0ede979e28ed1920492b40f במקום <public-key-id> .

הגדרת משתני build

מעמיסים מסוג A/B חייבים לעמוד בקריטריונים הבאים של משתני build:

חייב להגדיר עבור יעד A/B
  • AB_OTA_UPDATER := true
  • AB_OTA_PARTITIONS := \
    boot \
    system \
    vendor
    מחיצות אחרות המעודכנות דרך update_engine (רדיו, מנהל אתחול, וכו ')
  • PRODUCT_PACKAGES += \
    update_engine \
    update_verifier
לדוגמא, מתייחסים /device/google/marlin/+/android-7.1.0_r1/device-common.mk . לחלופין, ניתן לנהל את הפוסט להתקין (אבל מראש אתחול מחדש) dex2oat צעד מתואר הידור .
מומלץ בחום למטרה A/B
  • גדר TARGET_NO_RECOVERY := true
  • גדר BOARD_USES_RECOVERY_AS_BOOT := true
  • אל תגדיר BOARD_RECOVERYIMAGE_PARTITION_SIZE
לא ניתן להגדיר עבור יעד A/B
  • BOARD_CACHEIMAGE_PARTITION_SIZE
  • BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE
אופציונלי לבניית באגים PRODUCT_PACKAGES_DEBUG += update_engine_client

הגדרת מחיצות (חריצים)

מכשירי A/B אינם זקוקים למחיצת שחזור או מחיצת מטמון מכיוון ש- Android אינה משתמשת יותר במחיצות אלה. מחיצת הנתונים משמשת כעת לחבילת OTA שהורדה, וקוד תמונת השחזור נמצא במחיצת האתחול. כל מחיצות שאינן A / B-ed אמור להיקרא כדלקמן (חריצי תמיד נקראים , a b , וכו '): boot_a , boot_b , system_a , system_b , vendor_a , vendor_b .

מטמון

עבור עדכונים שאינם A/B, מחיצת המטמון שימשה לאחסון חבילות OTA שהורדו ולאחסון בלוקים באופן זמני בעת החלת עדכונים. מעולם לא הייתה דרך טובה להגדיל את מחיצת המטמון: עד כמה היא צריכה להיות תלויה באילו עדכונים אתה רוצה ליישם. המקרה הגרוע ביותר יהיה מחיצת מטמון גדולה כמו תמונת המערכת. עם עדכוני A/B אין צורך לאחסן בלוקים (מכיוון שאתה תמיד כותב למחיצה שאינה בשימוש כרגע) ועם הזרמת A/B אין צורך להוריד את כל חבילת OTA לפני החלתה.

התאוששות

דיסק RAM ההתאוששות הנמצא עתה ב boot.img הקובץ. כאשר נכנס התאוששות, את מנהל האתחול לא יכול לשים את skip_initramfs אפשרות בשורת הפקודה kernel.

עבור עדכונים שאינם A/B, מחיצת השחזור מכילה את הקוד המשמש להחלת עדכונים. עדכונים / B מוחלים על ידי update_engine פועל תמונת מערכת הממוגפת הרגילה. עדיין קיים מצב שחזור המשמש ליישום איפוס נתוני יצרן וטעינת צד של חבילות עדכונים (משם הגיע השם "שחזור"). הקוד והנתונים למצב שחזור מאוחסנים במחיצת האתחול הרגילה ב- ramdisk; כדי לאתחל את תמונת המערכת, מטען האתחול אומר לגרעין לדלג על ramdisk (אחרת המכשיר יתחיל למצב שחזור. מצב השחזור קטן (והרבה ממנו כבר היה במחיצת האתחול), כך שמחיצת האתחול לא גדלה במידה.

Fstab

slotselect טיעון חייב להיות על הקו עבור מחיצות A / B-ed. לדוגמה:

<path-to-block-device>/vendor  /vendor  ext4  ro
wait,verify=<path-to-block-device>/metadata,slotselect

אין מחיצה אמורה להיקרא vendor . במקום זאת, החלוקה vendor_a או vendor_b ייבחר רכוב על /vendor נקודת עיגון.

טיעוני חריץ ליבה

הסיומת המשבצת הנוכחית אמור לעבור גם דרך עץ התקן ספציפי צומת (DT) ( /firmware/android/slot_suffix ) או דרך androidboot.slot_suffix שורת פקוד הקרנל או ויכוח bootconfig.

כברירת מחדל, fastboot מהבהב את החריץ הנוכחי בהתקן A/B. אם חבילת העדכון מכילה גם תמונות עבור החריץ השני, הלא שוטף, fastboot מהבהב גם את התמונות האלה. האפשרויות הזמינות כוללות:

  • --slot SLOT . בטל את התנהגות ברירת המחדל והנח את bootboot להבהב את החריץ המועבר כוויכוח.
  • --set-active [ SLOT ] . הגדר את החריץ כפעיל. אם לא צוין ארגומנט אופציונלי, החריץ הנוכחי מוגדר כפעיל.
  • fastboot --help . קבל פרטים על פקודות.

אם fastboot סככת מנהל אתחול, הוא אמור לתמוך את פקוד set_active <slot> כי סטי חריץ הפעיל הנוכחי כדי החריץ נתון (זה חייב גם לנקות את הדגל לאתחול עבור החריץ כי ולאפס את ספירת retry לערכי ברירת מחדל). מטען האתחול צריך גם לתמוך במשתנים הבאים:

  • has-slot:<partition-base-name-without-suffix> . מחזירה "כן" אם המחיצה הנתונה תומכת בחריצים, "לא" אחרת.
  • current-slot . מחזירה את סיומת החריץ שתאותחל מההמשך.
  • slot-count . מחזירה מספר שלם המייצג את מספר המשבצות הזמינות. נכון לעכשיו, שני חריצים נתמכים כך ערך זה הוא 2 .
  • slot-successful:<slot-suffix> . מחזירה "כן" אם החריץ הנתון סומן כאתחול מוצלח, "לא" אחרת.
  • slot-unbootable:<slot-suffix> . מחזירה "כן" אם החריץ הנתון מסומן כבלתי ניתן לאתחול, "לא" אחרת.
  • slot-retry-count . מספר נסיונות חוזרים שנותרו כדי לאתחל את החריץ הנתון.

כדי להציג את כל המשתנים, להריץ fastboot getvar all .

יצירת חבילות OTA

כלי חבילת OTA בצעו את אותן פקודות פקוד עבור non-A / B התקנים. target_files.zip הקובץ חייב להיווצר על ידי הגדרת המשתנים לבנות עבור היעד A / B. כלי חבילת OTA מזהים ויוצרים אוטומטית חבילות בפורמט לעדכון A/B.

דוגמאות:

  • כדי ליצור OTA מלא:
    ./build/make/tools/releasetools/ota_from_target_files \
        dist_output/tardis-target_files.zip \
        ota_update.zip
    
  • כדי ליצור OTA מצטבר:
    ./build/make/tools/releasetools/ota_from_target_files \
        -i PREVIOUS-tardis-target_files.zip \
        dist_output/tardis-target_files.zip \
        incremental_ota_update.zip
    

הגדרת מחיצות

update_engine יכול לעדכן כל זוג מחיצות A / B מוגדרים באותו דיסק. זוג המחיצות יש קידומת משותפת (כגון system או boot ) וסיומת לכול חריץ (כגון _a ). רשימת מחיצות אשר מחולל מטען מגדיר עדכון מוגדר על ידי AB_OTA_PARTITIONS להפוך משתנה.

לדוגמה, אם זוג מחיצות bootloader_a ו booloader_b כלול ( _a ו _b הם סיומות החריץ), אתה יכול לעדכן מחיצות אלה על ידי הציון הבא לתצורת המוצר או לוח:

AB_OTA_PARTITIONS := \
  boot \
  system \
  bootloader

כל מחיצות עודכן על ידי update_engine לא חייב להיות שונה על ידי שאר המערכת. במהלך עדכונים מצטברים או דלתא, הנתונים בינאריים מהחריץ הנוכחי משמשים להפקת נתון בחריץ החדש. כל שינוי עלול לגרום לנתוני החריצים החדשים להיכשל באימות במהלך תהליך העדכון, ולכן להיכשל בעדכון.

קביעת תצורה לאחר ההתקנה

תוכל להגדיר את השלב שלאחר ההתקנה באופן שונה עבור כל מחיצה מעודכנת באמצעות קבוצה של זוגות ערך-מפתח. כדי להפעיל תכנית ממוקמת /system/usr/bin/postinst ב תמונה חדשה, לציין את הנתיב יחסית לבסיס של מערכת הקבצים במחיצת המערכת.

לדוגמה, usr/bin/postinst היא system/usr/bin/postinst (אם לא באמצעות דיסק RAM). בנוסף, ציין את סוג מערכת הקבצים כדי לעבור אל mount(2) קריאת המערכת. הוסף את הקוד הבא המוצר או מכשיר .mk הקבצים (אם רלוונטי):

AB_OTA_POSTINSTALL_CONFIG += \
  RUN_POSTINSTALL_system=true \
  POSTINSTALL_PATH_system=usr/bin/postinst \
  FILESYSTEM_TYPE_system=ext4

הידור

מטעמי אבטחה, system_server לא יכול להשתמש רק ב-זמן (JIT) הידור. אמצעי זה עליך להדר לקראת קבצי odex זמן system_server ואת התלות שלו לכל הפחות; כל דבר אחר הוא אופציונלי.

כדי לאסוף אפליקציות ברקע, עליך להוסיף את הדברים הבאים לתצורת המכשיר של המוצר (במכשיר המוצר.mk):

  1. כלול את הרכיבים המקומיים במבנה כדי לוודא שסקריפט האוסף והקבצים הבינאריים נאספים ונכללים בתמונת המערכת.
      # A/B OTA dexopt package
      PRODUCT_PACKAGES += otapreopt_script
    
  2. חברו את התסריט הידור כדי update_engine כך פועל כמו פוסט-שלב ההתקנה.
      # A/B OTA dexopt update_engine hookup
      AB_OTA_POSTINSTALL_CONFIG += \
        RUN_POSTINSTALL_system=true \
        POSTINSTALL_PATH_system=system/bin/otapreopt_script \
        FILESYSTEM_TYPE_system=ext4 \
        POSTINSTALL_OPTIONAL_system=true
    

לקבלת עזרה בהתקנת קבצי preopted במחיצת המערכת השנייה בשימוש, מתייחס התקנת אתחול הראשית של קבצי DEX_PREOPT .