Android 10 תומך במחיצות דינמיות, מערכת מחיצות במרחב המשתמש שאפשר ליצור בה מחיצות, לשנות את הגודל שלהן ולהשמיד אותן במהלך עדכונים אוויריים (OTA).
בדף הזה מוסבר איך לקוחות OTA משנים את הגודל של מחיצות דינמיות במהלך עדכון למכשירי A/B שהושקו ללא תמיכה במחיצות דינמיות, ואיך לקוחות OTA משדרגים ל-Android 10.
רקע
במהלך עדכון של מכשיר A/B לתמיכה במחיצות דינמיות, טבלת המחיצות של GUID (GPT) במכשיר נשמרת, כך שאין במכשיר מחיצה מסוג super
. המטא-נתונים מאוחסנים ב-system_a
וב-system_b
, אבל אפשר לשנות את BOARD_SUPER_PARTITION_METADATA_DEVICE
כדי להתאים אישית את המיקום.
בכל אחד מהמכשירים החסומים יש שני משבצות למטא-נתונים. נעשה שימוש רק בחריץ מטא-נתונים אחד בכל מכשיר בלוקים. לדוגמה, המטא-נתונים 0 ב-system_a
והמטא-נתונים 1 ב-system_b
תואמים למחיצות בחריצי A ו-B, בהתאמה. בזמן הריצה, לא משנה איזה חריץ מתעדכן.
בדף הזה, חריצי המטא-נתונים נקראים Metadata S (מקור) ו-Metadata T (יעד). באופן דומה, המחיצות נקראות system_s
, vendor_t
וכן הלאה.
מידע נוסף על הגדרות של מערכת build זמין במאמר שדרוג מכשירים.
למידע נוסף על האופן שבו מחיצות שייכות לקבוצות עדכון, ראו שינויים בהגדרות הלוח במכשירים חדשים.
דוגמה למטא-נתונים במכשיר:
- התקן בלוקים פיזי
system_a
- מטא-נתונים 0
- קבוצה
foo_a
- מחיצה לוגית (דינמית)
system_a
- חלוקה לוגית (דינמית)
product_services_a
- מחיצות אחרות שעודכנו על ידי Foo
- מחיצה לוגית (דינמית)
- קבוצה
bar_a
- מחיצה לוגית (דינמית)
vendor_a
- מחיצה לוגית (דינמית)
product_a
- מחיצות אחרות שעודכנו על ידי Bar
- מחיצה לוגית (דינמית)
- קבוצה
- מטא-נתונים 1 (לא בשימוש)
- מטא-נתונים 0
- התקן בלוקים פיזי
system_b
- מטא-נתונים 0 (לא בשימוש)
- מטא-נתונים 1
- קבוצה foo_b
- מחיצה לוגית (דינמית)
system_b
- מחיצה לוגית (דינמית)
product_services_b
- מחיצות אחרות שעודכנו על ידי Foo
- מחיצה לוגית (דינמית)
- Group bar_b
- חלוקה לוגית (דינמית)
vendor_b
- מחיצה לוגית (דינמית)
product_b
- מחיצות אחרות שעודכנו על ידי הסרגל
- חלוקה לוגית (דינמית)
- קבוצה foo_b
אפשר להשתמש בכלי lpdump
בקטע system/extras/partition_tools
כדי לדגום את המטא-נתונים במכשיר. לדוגמה:
lpdump --slot 0 /dev/block/by-name/system_a
lpdump --slot 1 /dev/block/by-name/system_b
עדכון רטרופי
במכשירים עם Android מגרסה 9 ומטה, לקוח OTA במכשיר לא תומך במיפוי של מחיצות דינמיות לפני העדכון. נוצרת קבוצת תיקונים נוספת כדי שאפשר יהיה להחיל את המיפוי ישירות על המחיצות הפיזיות הקיימות.
מחולל ה-OTA בונה את קובץ super.img
הסופי שמכיל את התוכן של כל המחיצות הדינמיות, ולאחר מכן מפצל את התמונה למספר תמונות שתואמות לגדלים של מכשירי הבלוק הפיזיים שתואמים למערכת, לספק וכן הלאה. השמות של התמונות האלה הם super_system.img
, super_vendor.img
וכן הלאה.
לקוח ה-OTA מחיל את התמונות האלה על המחיצות הפיזיות, במקום להחיל את התמונות על המחיצות הלוגיות (הדינמיות).
מכיוון שלקוח ה-OTA לא יודע למפות מחיצות דינמיות, כל השלבים שלאחר ההתקנה מושבתים באופן אוטומטי במחיצות האלה כשחבילת העדכון נוצרת. פרטים נוספים זמינים במאמר הגדרה לאחר ההתקנה.
תהליך העדכון זהה לתהליך ב-Android 9.
לפני העדכון:
ro.boot.dynamic_partitions= ro.boot.dynamic_partitions_retrofit=
אחרי העדכון:
ro.boot.dynamic_partitions=true ro.boot.dynamic_partitions_retrofit=true
עדכונים עתידיים לאחר שדרוג
אחרי עדכון ההתאמה לאחור, לקוח ה-OTA מתעדכן לעבודה עם מחיצות דינמיות. היקפי המידע של מחיצות המקור אף פעם לא נפרסים על פני מחיצות פיזיות של יעד.
תהליך העדכון באמצעות חבילת עדכון רגילה
- מאתחלים את המטא-נתונים של המחיצה
super
.-
ליצור מטא-נתונים חדשים M מ-מטא-נתונים על S (מטא-נתונים של מקור).
לדוגמה, אם המטא-נתונים S משתמשים ב-[
system_s
,vendor_s
, product_s
] כמכשירי חסימה, אז המטא-נתונים החדשים M משתמשים ב-[system_t
,vendor_t
, product_t
] כמכשירי חסימה. כל הקבוצות והמחיצות נמחקות ב-M. -
מוסיפים קבוצות יעד ומחיצות בהתאם לשדה
dynamic_partition_metadata
במניפסט העדכון. הגודל של כל מחיצה מופיע ב-new_partition_info
. - כתיבת M למטא-נתונים T.
- ממפים את המחיצות שנוספו בממפה של המכשיר כמחיצות שאפשר לכתוב בהן.
-
ליצור מטא-נתונים חדשים M מ-מטא-נתונים על S (מטא-נתונים של מקור).
לדוגמה, אם המטא-נתונים S משתמשים ב-[
- מחילים את העדכון במכשירים שחוסמו.
- במידת הצורך, ממפים את המחיצות של המקור בממפה של המכשיר בתור קריאה בלבד. הפעולה הזו הכרחית להתקנה ממקור לא ידוע, כי מחיצות המקור לא ממופות לפני העדכון.
- צריך להחיל עדכון מלא או עדכון דלתא על כל המכשירים החסומים במיקום היעד.
- מחברים את המחיצות כדי להריץ את הסקריפט שלאחר ההתקנה, ואז מנתקים את המחיצות.
- ביטול המיפוי של המחיצות היעד
תהליך העדכון באמצעות חבילת עדכון ל-retrofit
אם חבילת העדכון של ההתקנה מחדש מוחלת במכשיר שכבר
מפעיל מחיצות דינמיות, לקוח ה-OTA מחיל את קובץ ה-super.img
המפוצל ישירות על מכשירי בלוקים. תהליך העדכון דומה לעדכון של ציוד משומש. פרטים נוספים זמינים במאמר התאמה לאחור של עדכון.
לדוגמה, נניח את הפרטים הבאים:
- חריץ A הוא החריץ הפעיל.
-
system_a
מכיל את המטא-נתונים הפעילים בחריץ 0. -
system_a
,vendor_a
ו-product_a
משמשים כהתקני בלוקים.
כשלקוח OTA מקבל חבילת עדכון לשדרוג מכשירים קיימים, היא חלה על super_system.img
במכשיר הפיזי system_b
, על super_vendor.img
במכשיר הפיזי vendor_b
ועל super_product.img
במכשיר הפיזי product_b
.
מכשיר הבלוק הפיזי system_b
מכיל את המטא-נתונים הנכונים
כדי למפות את הערכים הלוגיים system_b
, vendor_b
ו-product_b
בזמן ההפעלה.
יצירת חבילות עדכון
OTA מצטבר
כשיוצרים עדכוני OTA מצטברים למכשירים מותאמים, העדכונים תלויים בכך שהגדרות PRODUCT_USE_DYNAMIC_PARTITIONS
ו-PRODUCT_RETROFIT_DYNAMIC_PARTITIONS
מוגדרות בגרסה הבסיסית או לא.
-
אם המשתנים לא מוגדרים ב-build הבסיסי , זהו עדכון למערכות קיימות. חבילת העדכון מכילה את הקובץ המפוצל
super.img
ומשביתה את השלב שלאחר ההתקנה. - אם ה-build הבסיסי כן מגדיר את המשתנים, הוא זהה לעדכון טיפוסי עם מחיצות דינמיות. חבילת העדכון מכילה את התמונות של המחיצות הלוגיות (הדינמיות). אפשר להפעיל את השלב שלאחר ההתקנה.
OTA מלא
שתי חבילות OTA מלאות נוצרות למכשירים מותאמים.
-
$(PRODUCT)-ota-retrofit-$(TAG).zip
תמיד מכיל את הפיצולsuper.img
ומשבית את השלב שלאחר ההתקנה לעדכון של ציוד משומש.-
הוא נוצר עם ארגומנט נוסף
--retrofit_dynamic_partitions
לסקריפטota_from_target_files
. - אפשר להחיל אותו על כל הגרסאות הבנויות.
-
הוא נוצר עם ארגומנט נוסף
-
$(PRODUCT)-ota-$(TAG).zip
מכיל תמונות לוגיות לעדכונים עתידיים.- יש להחיל את ההגדרה הזו רק על גרסאות build שבהן מופעלות מחיצות דינמיות. בהמשך מוסבר איך אנחנו אוכפים את המדיניות הזו.
דחיית עדכון שלא השתנה לגבי גרסאות build ישנות
יש להחיל את חבילת ה-OTA המלאה הרגילה רק על גרסאות build שבהן מופעלים מחיצות דינמיות. אם שרת ה-OTA מוגדר בצורה שגויה ומעביר את החבילות האלה למכשירים עם Android מגרסה 9 ומטה, המכשירים לא יוכלו להפעיל את עצמם. לקוח ה-OTA בגרסאות Android 9 ואילך לא יכול להבדיל בין חבילת OTA שהותאמה לשימוש חוזר לבין חבילת OTA מלאה רגילה, ולכן הלקוח לא ידחה את החבילה המלאה.
כדי למנוע מהמכשיר לקבל את חבילת ה-OTA המלאה, אפשר לדרוש שלב לאחר ההתקנה כדי לבדוק את ההגדרות הקיימות במכשיר. לדוגמה:
device/device_name/dynamic_partitions/check_dynamic_partitions
#!/system/bin/sh DP_PROPERTY_NAME="ro.boot.dynamic_partitions" DP_RETROFIT_PROPERTY_NAME="ro.boot.dynamic_partitions_retrofit" DP_PROPERTY=$(getprop ${DP_PROPERTY_NAME}) DP_RETROFIT_PROPERTY=$(getprop ${DP_RETROFIT_PROPERTY_NAME}) if [ "${DP_PROPERTY}" != "true" ] || [ "${DP_RETROFIT_PROPERTY}" != "true" ] ; then echo "Error: applied non-retrofit update on build without dynamic" \ "partitions." echo "${DP_PROPERTY_NAME}=${DP_PROPERTY}" echo "${DP_RETROFIT_PROPERTY_NAME}=${DP_RETROFIT_PROPERTY}" exit 1 fi
device/device_name/dynamic_partitions/Android.mk
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE:= check_dynamic_partitions LOCAL_MODULE_TAGS := optional LOCAL_MODULE_CLASS := EXECUTABLES LOCAL_SRC_FILES := check_dynamic_partitions LOCAL_PRODUCT_MODULE := true include $(BUILD_PREBUILT)
device/device_name/device.mk
PRODUCT_PACKAGES += check_dynamic_partitions # OPTIONAL=false so that the error in check_dynamic_partitions will be # propagated to OTA client. AB_OTA_POSTINSTALL_CONFIG += \ RUN_POSTINSTALL_product=true \ POSTINSTALL_PATH_product=bin/check_dynamic_partitions \ FILESYSTEM_TYPE_product=ext4 \ POSTINSTALL_OPTIONAL_product=false \
כשחבילת ה-OTA הרגילה חלה על מכשיר בלי מחיצות דינמיות מופעלות, לקוח ה-OTA מפעיל את check_dynamic_partitions
כשלב לאחר ההתקנה ומסרב לעדכון.