יצרני 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/
.
עליך גם ליישם את מכונת המדינה המוצגת להלן:

הגדרת הגרעין
ליישום עדכוני מערכת A/B:
- Cherrypick את סדרת תיקוני הגרעין הבאה (במידת הצורך):
- אם אתחול ללא ramdisk ושימוש "אתחול כמו התאוששות", cherrypick android-review.googlesource.com/#/c/158491/ .
- כדי להגדיר dm-אמתה ללא ramdisk, cherrypick android-review.googlesource.com/#/q/status:merged+project:kernel/common+branch:android-3.18+topic:A_B_Changes_3.18 .
- ודא טיעונים שורת הפקודה הקרנל להכיל את הטיעונים הנוספים הבאים:
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-אמתה ) . - הוסף את אישור .X509 המכיל את המפתח הציבורי למפתח המפתח של המערכת:
- העתק את האישור .X509 מעוצב בתוך
.der
בפורמט לשורש שלkernel
בספרייה. אם האישור .X509 מעוצב כמו.pem
קובץ, השתמש בנוסחה הבאהopenssl
הפקודה כדי להמיר מ.pem
כדי.der
פורמט:openssl x509 -in <x509-pem-certificate> -outform der -out <x509-der-certificate>
- בנה את
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 מעיד על קיומו של המפתח הציבורי מחזיק מפתחות מערכת (שיא מציין את מזהה המפתח הציבורי). - החלף את החלל עם
#
ולהעביר אותו כמו<public-key-id>
בשורת הפקודה kernel. לדוגמה, לעבורAndroid:#7e4333f9bba00adfe0ede979e28ed1920492b40f
במקום<public-key-id>
.
- העתק את האישור .X509 מעוצב בתוך
הגדרת משתני build
מעמיסים מסוג A/B חייבים לעמוד בקריטריונים הבאים של משתני build:
חייב להגדיר עבור יעד A/B |
/device/google/marlin/+/android-7.1.0_r1/device-common.mk . לחלופין, ניתן לנהל את הפוסט להתקין (אבל מראש אתחול מחדש) dex2oat צעד מתואר הידור . |
---|---|
מומלץ בחום למטרה A/B |
|
לא ניתן להגדיר עבור יעד A/B |
|
אופציונלי לבניית באגים | 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):
- כלול את הרכיבים המקומיים במבנה כדי לוודא שסקריפט האוסף והקבצים הבינאריים נאספים ונכללים בתמונת המערכת.
# A/B OTA dexopt package PRODUCT_PACKAGES += otapreopt_script
- חברו את התסריט הידור כדי
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 .