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
- מחיצה לוגית (דינמית)
- קבוצה bar_b
- מחיצה לוגית (דינמית)
vendor_b
- מחיצה לוגית (דינמית)
product_b
- מחיצות אחרות שעודכנו על ידי Bar
- מחיצה לוגית (דינמית)
- קבוצה 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 generator יוצר את קובץ ה-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
אם חבילת העדכון של ה-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
כשלב לאחר ההתקנה ומסרב לעדכון.