הטמעת A/B וירטואלית

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

בנה דגלים

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

עבור מכשירים המופעלים עם A/B ​​וירטואלי, הגדר אותם כך שיורש את תצורת בסיס התקן A/B וירטואלי:

$(call inherit-product, \
    $(SRC_TARGET_DIR)/product/virtual_ab_ota.mk)

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

עבור Android 13 ומעלה, כדי לאפשר צילומי מצב דחוסים עם Virtual A/B, ירשו את תצורת הבסיס הבאה:

$(call inherit-product, $(SRC_TARGET_DIR)/product/generic_ramdisk.mk)
$(call inherit-product, \
    $(SRC_TARGET_DIR)/product/virtual_ab_ota/android_t_baseline.mk)

זה מאפשר צילומי מרחב משתמש עם Virtual A/B תוך שימוש בשיטת דחיסה ללא הפעלה. לאחר מכן תוכל להגדיר את שיטת הדחיסה לאחת מהשיטות הנתמכות, gz , zstd ו- lz4 .

PRODUCT_VIRTUAL_AB_COMPRESSION_METHOD := lz4

עבור Android 12, כדי לאפשר צילומי מצב דחוסים עם Virtual A/B, ירשו את תצורת הבסיס הבאה:

$(call inherit-product, $(SRC_TARGET_DIR)/product/generic_ramdisk.mk)
$(call inherit-product, \
    $(SRC_TARGET_DIR)/product/virtual_ab_ota/compression.mk)

דחיסת XOR

עבור מכשירים המשדרגים ל-Android 13 ומעלה, תכונת הדחיסה של XOR אינה מופעלת כברירת מחדל. כדי לאפשר דחיסת XOR, הוסף את הדברים הבאים לקובץ .mk של המכשיר.

PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.compression.xor.enabled=true

דחיסת XOR מופעלת כברירת מחדל עבור מכשירים שיורשים מ- android_t_baseline.mk .

מיזוג שטחי משתמש

עבור מכשירים שמשדרגים ל-Android 13 ומעלה, תהליך מיזוג מרחב המשתמש כפי שמתואר בשכבות של Device-Mapper אינו מופעל כברירת מחדל. כדי לאפשר מיזוג שטחי משתמש, הוסף את השורה הבאה לקובץ .mk של המכשיר:

PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.userspace.snapshots.enabled=true

מיזוג שטחי משתמש מופעל כברירת מחדל במכשירים המופעלים עם 13 ומעלה.

בקרת אתחול HAL

בקרת האתחול HAL מספקת ממשק עבור לקוחות OTA לשליטה בחריצי אתחול. Virtual A/B דורש שדרוג גרסה מינורי של HAL בקרת האתחול מכיוון שנדרשים ממשקי API נוספים כדי להבטיח שהמטען האתחול מוגן במהלך מהבהב/איפוס להגדרות היצרן. ראה IBootControl.hal ו- types.hal לגרסה העדכנית ביותר של הגדרת HAL.

// hardware/interfaces/boot/1.1/types.hal
enum MergeStatus : uint8_t {
    NONE, UNKNOWN, SNAPSHOTTED, MERGING, CANCELLED };

// hardware/interfaces/boot/1.1/IBootControl.hal
package android.hardware.boot@1.1;
interface IBootControl extends @1.0::IBootControl {
    setSnapshotMergeStatus(MergeStatus status)
        generates (bool success);
    getSnapshotMergeStatus()
        generates (MergeStatus status);
}
// Recommended implementation

Return<bool> BootControl::setSnapshotMergeStatus(MergeStatus v) {
    // Write value to persistent storage
    // e.g. misc partition (using libbootloader_message)
    // bootloader rejects wipe when status is SNAPSHOTTED
    // or MERGING
}

שינויים ב-Fstab

השלמות של מחיצת המטא נתונים חיונית לתהליך האתחול, במיוחד מיד לאחר החלת עדכון OTA. לכן, יש לבדוק את מחיצת המטא נתונים לפני first_stage_init מעלה אותה. כדי להבטיח שזה יקרה, הוסף את הדגל check fs_mgr לערך עבור /metadata . להלן דוגמה:

/dev/block/by-name/metadata /metadata ext4 noatime,nosuid,nodev,discard,sync wait,formattable,first_stage_mount,check

דרישות הליבה

כדי לאפשר צילום מצב, הגדר את CONFIG_DM_SNAPSHOT ל- true .

עבור מכשירים המשתמשים ב-F2FS, כלול את הדגל f2fs: ייצוא FS_NOCOW_FL לתיקון ליבת המשתמש כדי לתקן הצמדת קבצים. כלול את ה- f2fs: תומך גם בתיקון ליבת קבצים מוצמדים .

A/B וירטואלי מסתמך על תכונות שנוספו בגרסת ליבה 4.3: סיבית מצב הגלישה במטרות snapshot snapshot-merge . לכל המכשירים המופעלים עם אנדרואיד 9 ואילך כבר אמורים להיות גרסת ליבה 4.4 ואילך.

כדי לאפשר צילומי מצב דחוסים, גרסת הליבה המינימלית הנתמכת היא 4.19. הגדר CONFIG_DM_USER=m או CONFIG_DM_USER=y . אם משתמשים בקודם (מודול), יש לטעון את המודול ב-ramdisk של השלב הראשון. ניתן להשיג זאת על ידי הוספת השורה הבאה למכשיר Makefile:

BOARD_GENERIC_RAMDISK_KERNEL_MODULES_LOAD := dm-user.ko

תקן מחדש במכשירים המשדרגים לאנדרואיד 11

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

  • מיקום קבצי COW - עבור התקני הפעלה, לקוח OTA משתמש בכל השטח הריק הזמין במחיצת העל לפני השימוש בשטח ב- /data . עבור התקני תיקון, תמיד יש מספיק מקום במחיצת העל כך שקובץ COW לעולם לא ייווצר ב- /data .

  • דגלים של תכונה בזמן בנייה — עבור מכשירים המשלבים A/B ​​וירטואלי, הן PRODUCT_VIRTUAL_AB_OTA והן PRODUCT_VIRTUAL_AB_OTA_RETROFIT מוגדרות כ- true , כפי שמוצג להלן:

    (call inherit-product, \
        (SRC_TARGET_DIR)/product/virtual_ab_ota_retrofit.mk)
    
  • גודל מחיצת סופר - מכשירים המופעלים עם A/B ​​וירטואלי יכולים לחתוך BOARD_SUPER_PARTITION_SIZE לחצי מכיוון שחריצי B אינם נמצאים במחיצת העל. מכשירים שמתאימים A/B ​​וירטואלית לאחור שומרים על גודל מחיצת העל הישנה, ​​כך ש- BOARD_SUPER_PARTITION_SIZE גדול או שווה ל -2 * סכום (גודל קבוצות עדכון) + תקורה , שבתורו גדול או שווה ל -2 * סכום (גודל מחיצות) + תקורה .

שינויים בטעינת האתחול

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

לפני מחיקת /data , סיים את המיזוג בשחזור או החזרה לאחור בהתאם למצב המכשיר:

  • אם המבנה החדש עלה בהצלחה בעבר, סיים את ההעברה.
  • אחרת, חזור אל המשבצת הישנה:
    • עבור מחיצות דינמיות, חזור למצב הקודם.
    • עבור מחיצות סטטיות, הגדר את החריץ הפעיל לחריץ הישן.

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

  1. הטמיע את בקרת האתחול HAL כך שמטען האתחול יוכל לקרוא את הערך שהוגדר בשיטת setSnapshotMergeStatus() ‎.
  2. אם סטטוס המיזוג הוא MERGING , או אם סטטוס המיזוג הוא SNAPSHOTTED והחריץ השתנה למשבצת המעודכנת לאחרונה, יש לדחות בקשות למחיקת userdata , metadata או מחיצה המאחסנת את מצב המיזוג במטען האתחול.
  3. הטמע את הפקודה fastboot snapshot-update cancel כך שמשתמשים יוכלו לאותת למטען האתחול שהם רוצים לעקוף את מנגנון ההגנה הזה.
  4. שנה כלים או סקריפטים מהבהבים מותאמים אישית כדי להנפיק fastboot snapshot-update cancel בעת מהבהבת המכשיר כולו. זה בטוח להנפקה מכיוון שהבהוב של המכשיר כולו מסיר את ה-OTA. כלי עבודה יכולים לזהות פקודה זו בזמן ריצה על ידי הטמעת fastboot getvar snapshot-update-status . פקודה זו עוזרת להבדיל בין מצבי שגיאה.

דוגמא

struct VirtualAbState {
    uint8_t StructVersion;
    uint8_t MergeStatus;
    uint8_t SourceSlot;
};

bool ShouldPreventUserdataWipe() {
    VirtualAbState state;
    if (!ReadVirtualAbState(&state)) ...
    return state.MergeStatus == MergeStatus::MERGING ||
           (state.MergeStatus == MergeStatus::SNAPSHOTTED &&
            state.SourceSlot != CurrentSlot()));
}

שינויים בכלי Fastboot

אנדרואיד 11 מבצעת את השינויים הבאים בפרוטוקול fastboot:

  • getvar snapshot-update-status - מחזירה את הערך שבקרת האתחול HAL מסר למטען האתחול:
    • אם המצב הוא MERGING , טוען האתחול חייב להחזיר merging .
    • אם המצב הוא SNAPSHOTTED , טוען האתחול חייב להחזיר snapshotted .
    • אחרת, טוען האתחול חייב להחזיר none .
  • snapshot-update merge - משלים פעולת מיזוג, אתחול לשחזור/fastbootd במידת הצורך. פקודה זו תקפה רק אם snapshot-update-status merging , והיא נתמכת רק ב-fastbootd.
  • snapshot-update cancel — מגדיר את מצב המיזוג של בקרת האתחול HAL ל- CANCELLED . פקודה זו אינה חוקית כאשר המכשיר נעול.
  • erase או wipe - erase או wipe של metadata , userdata או מחיצה שמחזיקה בסטטוס המיזוג עבור בקרת האתחול HAL אמורה לבדוק את סטטוס המיזוג של תמונת המצב. אם המצב הוא MERGING או SNAPSHOTTED , המכשיר אמור לבטל את הפעולה.
  • set_active — פקודת set_active שמשנה את המשבצת הפעילה צריכה לבדוק את מצב המיזוג של תמונת המצב. אם המצב הוא MERGING , המכשיר אמור לבטל את הפעולה. ניתן לשנות את החריץ בבטחה במצב SNAPSHOTTED .

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

  1. שאילתה getvar snapshot-update-status .
  2. אם merging או snapshotted , הפק את snapshot-update cancel .
  3. המשך בצעדים מהבהבים.

צמצם את דרישות האחסון

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

שיטות דחיסה של OTA

ניתן לכוונן חבילות OTA עבור מדדי ביצועים שונים. אנדרואיד מספקת מספר שיטות דחיסה נתמכות ( gz , lz4 , zstd ו- none ) שיש להן פשרות בין זמן ההתקנה, שימוש בשטח COW, זמן האתחול וזמן מיזוג תמונת מצב. אפשרות ברירת המחדל מופעלת עבור ab וירטואלית עם דחיסה היא gz compression method . (הערה: הביצועים היחסיים בין שיטות הדחיסה משתנים בהתאם למהירות המעבד ותפוקת האחסון שיכולים להשתנות בהתאם למכשיר. כל חבילות ה-OTA שנוצרו להלן מושבתות עם PostInstall, מה שיאט מעט את זמן האתחול. גודל המחיצה הדינמית הכולל של אוטה מלאה ללא דחיסה הוא 4.81 GB ).

OTA מצטבר ב-Pixel 6 Pro

זמן התקנה ללא שלב לאחר ההתקנה שימוש במקום פרה פוסט זמן אתחול של OTA זמן מיזוג של תמונת מצב
gz 24 דקות 1.18 ג'יגה-בייט 40.2 שניות 45.5 שניות
lz4 13 דקות 1.49 ג'יגה-בייט 37.4 שניות 37.1 שניות
אף אחד 13 דקות 2.90 ג'יגה-בייט 37.6 שניות 40.7 שניות

OTA מלא ב-Pixel 6 Pro

זמן התקנה ללא שלב לאחר ההתקנה שימוש בחלל COW פוסט זמן אתחול של OTA זמן מיזוג של תמונת מצב
gz 23 דקות 2.79 ג'יגה-בייט 24.9 שניות 41.7 שניות
lz4 12 דקות 3.46 ג'יגה-בייט 20.0 שניות 25.3 שניות
אף אחד 10 דק 4.85 ג'יגה-בייט 20.6 שניות 29.8 שניות