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
- Group foo_b
- מחיצה לוגית (דינמית)
system_b
- מחיצה לוגית (דינמית)
product_services_b
- מחיצות אחרות שעודכנו על ידי Foo
- מחיצה לוגית (דינמית)
- Group bar_b
- מחיצה לוגית (דינמית)
vendor_b
- מחיצה לוגית (דינמית)
product_b
- מחיצות אחרות שעודכנו על ידי Bar
- מחיצה לוגית (דינמית)
- Group 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
עדכונים עתידיים אחרי התאמה
אחרי עדכון ה-retrofit, לקוח ה-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.
- ממפים את המחיצות שנוספו ב-device mapper כניתנות לכתיבה.
-
יצירת מטא-נתונים חדשים M ממטא-נתונים S (מטא-נתוני המקור).
לדוגמה, אם במטא-נתונים S נעשה שימוש ב-[
- מחילים את העדכון על המכשירים החסומים.
- במידת הצורך, ממפים את מחיצות המקור בממפה המכשיר כקריאה בלבד. הפעולה הזו נדרשת להעלאה צדדית כי מחיצות המקור לא ממופות לפני העדכון.
- החלת עדכון מלא או עדכון דלתא על כל מכשירי הבלוק בחריץ היעד.
- מפעילים את המחיצות כדי להריץ את הסקריפט אחרי ההתקנה, ואז מבטלים את הפעלת המחיצות.
- מבטלים את המיפוי של מחיצות היעד.
תהליך העדכון באמצעות חבילת עדכון רטרו
אם חבילת העדכון של Retrofit מופעלת במכשיר שכבר מופעלות בו מחיצות דינמיות, לקוח ה-OTA מפעיל את קובץ super.img
במכשירי בלוק ישירות. תהליך העדכון דומה לעדכון רטרופיט. פרטים נוספים זמינים במאמר בנושא התאמת עדכון.
לדוגמה, נניח את הפרטים הבאים:
- חריץ A הוא החריץ הפעיל.
-
system_a
מכיל את המטא-נתונים הפעילים במשבצת 0. -
האפליקציות
system_a
,vendor_a
וגםproduct_a
משמשות כמכשירים לחסימה.
כשלקוח ה-OTA מקבל חבילת עדכון של retrofit, הוא מחיל את
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
בגרסת הבסיס.
-
אם בגרסת הבסיס לא מוגדרים המשתנים, זהו עדכון של התאמה מחדש. חבילת העדכון מכילה את הקובץ split
super.img
ומשביתה את השלב שאחרי ההתקנה. - אם בבניית הבסיס מוגדרים המשתנים, זה זהה לעדכון רגיל עם מחיצות דינמיות. חבילת העדכון מכילה את התמונות למחיצות לוגיות (דינמיות). אפשר להפעיל את שלב ההתקנה.
Full OTA
שתי חבילות OTA מלאות נוצרות למכשירים ששודרגו.
-
$(PRODUCT)-ota-retrofit-$(TAG).zip
תמיד מכיל פיצול שלsuper.img
ומשבית את השלב שאחרי ההתקנה לצורך התאמה של עדכון.-
הוא נוצר עם ארגומנט נוסף
--retrofit_dynamic_partitions
לסקריפטota_from_target_files
. - אפשר להחיל אותו על כל הגרסאות.
-
הוא נוצר עם ארגומנט נוסף
-
$(PRODUCT)-ota-$(TAG).zip
מכיל תמונות לוגיות לעדכונים עתידיים.- ההגדרה הזו חלה רק על גרסאות build שבהן מופעלות מחיצות דינמיות. בהמשך מפורטות הוראות לאכיפת ההגדרה הזו.
דחיית עדכון שלא מתאים לבנייה ישנה
חבילת ה-OTA המלאה הרגילה חלה רק על גרסאות build שמופעלות בהן מחיצות דינמיות. אם שרת ה-OTA מוגדר בצורה שגויה והוא דוחף את החבילות האלה למכשירים עם Android 9 או גרסה מוקדמת יותר, המכשירים לא יפעלו. לקוח ה-OTA ב-Android 9 ובגרסאות נמוכות יותר לא יכול להבדיל בין חבילת OTA של retrofit לבין חבילת 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
כשלב אחרי ההתקנה ודוחה את העדכון.