הקטנת גודל OTA

דף זה מתאר שינויים שנוספו ל-AOSP כדי לצמצם שינויים מיותרים בקבצים בין בנייה. מיישמי מכשירים שמתחזקים מערכות בנייה משלהם יכולים להשתמש במידע זה כמדריך לצמצום גודל העדכונים האויר-האוויר (OTA) שלהם.

עדכוני OTA של Android מכילים מדי פעם קבצים שהשתנו שאינם תואמים לשינויי קוד. הם למעשה בונים חפצי מערכת. זה יכול להתרחש כאשר אותו קוד, שנבנה בזמנים שונים, מספריות שונות, או במכונות שונות מייצר מספר רב של קבצים שהשתנו. עודף קבצים כזה מגדיל את גודלו של תיקון OTA, ומקשה לקבוע איזה קוד השתנה.

כדי להפוך את התוכן של OTA לשקוף יותר, AOSP כולל שינויי מערכת בנייה שנועדו להקטין את גודל תיקוני OTA. שינויים מיותרים בקבצים בין רכיבי בנייה בוטלו, ורק קבצים הקשורים לתיקון כלולים בעדכוני OTA. AOSP כולל גם כלי build diff , המסנן שינויים נפוצים הקשורים ל-build כדי לספק הבדל קובץ בנייה נקי יותר, וכלי מיפוי בלוקים , שעוזר לך לשמור על עקביות בהקצאת בלוקים.

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

  • שימוש ב- Brotli , אלגוריתם דחיסה גנרי ללא אובדן לתמונות מלאות בעדכוני מכשיר שאינם A/B. ניתן להתאים אישית את Brotli כדי לייעל את הדחיסה. בעדכונים גדולים יותר המורכבים משני בלוקים או יותר במערכת הקבצים (לדוגמה, system.img ), יצרני מכשירים או שותפים יכולים להוסיף אלגוריתמי דחיסה משלהם, ויכולים להשתמש באלגוריתמי דחיסה שונים על בלוקים שונים של אותו עדכון.
  • שימוש בדחיסה מחדש של Puffin , כלי תיקון דטרמיניסטי להוצאת זרמים, המטפל בפונקציות הדחיסה וההבדל ליצירת עדכון A/B OTA.
  • שינויים בשימוש בכלי דור דלתא, כגון אופן השימוש בספריית bsdiff לדחיסת תיקונים. באנדרואיד 9 ומעלה, הכלי bsdiff בוחר את אלגוריתם הדחיסה שייתן את תוצאות הדחיסה הטובות ביותר עבור תיקון.
  • שיפורים במנוע update_engine הביאו לצריכה פחותה של זיכרון כאשר מוחלים תיקונים עבור עדכוני מכשירי A/B.
  • שיפורים בפיצול קובצי zip גדולים עבור עדכוני OTA מבוססי בלוק. מצב ב- imgdiff מפצל קבצי APK גדולים מדי, בהתבסס על שמות ערכים. זה מייצר תיקון קטן יותר בהשוואה לפיצול קבצים באופן ליניארי ושימוש בכלי bsdiff כדי לדחוס אותם.

הסעיפים הבאים דנים בנושאים שונים המשפיעים על גדלי עדכוני OTA, הפתרונות שלהם ודוגמאות ליישום ב-AOSP.

סדר קבצים

בעיה : מערכות קבצים אינן מבטיחות סדר קבצים כאשר מבקשים רשימה של קבצים בספריה, למרות שבדרך כלל זה זהה לאותה קופה. כלים כגון ls ממיינים את התוצאות כברירת מחדל, אך פונקציית התווים הכלליים המשמשים פקודות כגון find ו- make אינן ממיינות. לפני השימוש בכלים אלה, עליך למיין את הפלטים.

פתרון : כאשר אתה משתמש בכלים כגון find make עם פונקציית התווים הכלליים, מיין את הפלט של פקודות אלה לפני השימוש בהן. בעת שימוש ב $(wildcard) או $(shell find) בקבצי Android.mk , מיין גם אותם. חלק מהכלים, כגון Java, עושים מיון קלט, אז לפני שאתה ממיין את הקבצים, ודא שהכלי שאתה משתמש בו לא עשה זאת כבר.

דוגמאות: מופעים רבים תוקנו במערכת הבנייה הליבה באמצעות המאקרו המובנה all-*-files-under , הכולל את all-cpp-files-under (כפי שמספר הגדרות נפרסו בקבצי makefile אחרים). לפרטים, עיין בפרטים הבאים:

בניית ספרייה

בעיה: שינוי הספרייה שבה הדברים בנויים יכול לגרום לקבצים הבינאריים להיות שונים. רוב הנתיבים ב-Android build הם נתיבים יחסיים ולכן __FILE__ ב-C/C++ אינו מהווה בעיה. עם זאת, סמלי ניפוי הבאגים מקודדים את שם הנתיב המלא כברירת מחדל, וה- .note.gnu.build-id נוצר מ-hashing הבינארי המופשט מראש, כך שהוא ישתנה אם סמלי ניפוי הבאגים ישתנו.

פתרון: AOSP הופך כעת נתיבי ניפוי באגים ליחסיים. לפרטים, עיין ב-CL: https://android.googlesource.com/platform/build/+/6a66a887baadc9eb3d0d60e26f748b8453e27a02 .

חותמות זמן

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

  • __DATE__/__TIME__/__TIMESTAMP__ בקוד C או C++.
  • חותמות זמן מוטמעות בארכיונים מבוססי zip.

פתרונות/דוגמאות: כדי להסיר חותמות זמן מפלט ה-build, השתמש בהוראות המפורטות להלן ב -__DATE__/__TIME__/__TIMESTAMP__ ב-C/C++. וחותמות זמן מוטבעות בארכיונים .

__DATE__/__TIME__/__TIMESTAMP__ ב-C/C++

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

חותמות זמן מוטמעות בארכיונים (מיקוד, צנצנת)

אנדרואיד 7.0 תיקנה את הבעיה של חותמות זמן מוטמעות בארכיוני zip על ידי הוספת -X לכל השימושים בפקודה zip . זה הסיר את ה-UID/GID של הבונה ואת חותמת הזמן המורחבת של Unix מקובץ ה-zip.

כלי חדש, ziptime (ממוקם ב- /platform/build/+/main/tools/ziptime/ ) מאפס את חותמות הזמן הרגילות בכותרות ה-zip. לפרטים, עיין בקובץ README .

הכלי signapk מגדיר חותמות זמן עבור קבצי ה-APK שעשויות להשתנות בהתאם לאזור הזמן של השרת. לפרטים, עיין ב-CL https://android.googlesource.com/platform/build/+/6c41036bcf35fe39162b50d27533f0f3bfab3028 .

מחרוזות גרסה

בעיה: למחרוזות גרסת APK צורפו לעתים קרובות את BUILD_NUMBER לגרסאות המקודדות הקשיחות שלהן. גם אם שום דבר אחר לא ישתנה ב-APK, כתוצאה מכך, ה-APK עדיין יהיה שונה.

פתרון: הסר את מספר ה-build ממחרוזת גרסת ה-APK.

דוגמאות:

אפשר חישוב אמת במכשיר

אם dm-verity מופעל במכשיר שלך, אז כלי OTA קולטים אוטומטית את תצורת ה-Verity שלך ומפעילים חישוב אמת במכשיר. זה מאפשר לחשב בלוקים של אמת במכשירי אנדרואיד, במקום להיות מאוחסנים כבייטים גולמיים בחבילת ה-OTA שלך. בלוקים של Verity יכולים להשתמש בכ-16MB עבור מחיצה של 2GB.

עם זאת, אימות המחשוב במכשיר יכול לקחת זמן רב. באופן ספציפי, קוד תיקון השגיאות העברה יכול להימשך זמן רב. במכשירי פיקסל, זה נוטה לקחת עד 10 דקות. במכשירים מתקדמים זה יכול לקחת יותר זמן. אם ברצונך להשבית חישוב אמת במכשיר, אך עדיין להפעיל את dm-verity, תוכל לעשות זאת על ידי העברת --disable_fec_computation לכלי ota_from_target_files בעת יצירת עדכון OTA. דגל זה משבית את חישוב האימות במכשיר במהלך עדכוני OTA. זה מקטין את זמן התקנת OTA, אבל מגדיל את גודל חבילת OTA. אם במכשיר שלך לא מופעל dm-verity, להעברת הדגל הזה אין השפעה.

כלי בנייה עקביים

בעיה: כלים שיוצרים קבצים מותקנים חייבים להיות עקביים (קלט נתון צריך תמיד לייצר את אותו פלט).

פתרונות/דוגמאות: נדרשו שינויים בכלי הבנייה הבאים:

השתמש בכלי build diff

במקרים בהם לא ניתן לבטל שינויים בקבצים הקשורים ל-build, AOSP כולל כלי build diff, target_files_diff.py לשימוש בהשוואה בין שתי חבילות קבצים. כלי זה מבצע הבדל רקורסיבי בין שני בניינים, למעט שינויים נפוצים הקשורים ל-build, כגון

  • שינויים צפויים בפלט ה-build (לדוגמה, עקב שינוי מספר build).
  • שינויים עקב בעיות ידועות במערכת הבנייה הנוכחית.

כדי להשתמש בכלי build diff, הפעל את הפקודה הבאה:

target_files_diff.py dir1 dir2

dir1 ו- dir2 הן ספריות בסיס המכילות את קובצי היעד שחולצו עבור כל build.

שמור על הקצאת בלוקים עקבית

עבור קובץ נתון, למרות שהתוכן שלו נשאר זהה בין שני בנייה, ייתכן שהבלוקים בפועל שמכילים את הנתונים השתנו. כתוצאה מכך, על המעדכן לבצע I/O מיותר כדי להזיז את הבלוקים לעדכון OTA.

בעדכון Virtual A/B OTA, I/O מיותר יכול להגדיל במידה ניכרת את שטח האחסון הדרוש לאחסון תמונת המצב של העתק-על-כתיבה. בעדכון OTA שאינו A/B, הזזת הבלוקים לעדכון OTA תורמת לזמן העדכון מכיוון שיש יותר I/O עקב מהלכי חסימה.

כדי לטפל בבעיה זו, ב-Android 7.0 Google הרחיבה את הכלי make_ext4fs לשמירה על עקביות של הקצאת בלוקים בין ה-builds. הכלי make_ext4fs מקבל דגל אופציונלי -d base_fs שמנסה להקצות קבצים לאותם בלוקים בעת יצירת תמונת ext4 . אתה יכול לחלץ את קובצי מיפוי הבלוק (כגון קובצי המפה base_fs ) מקובץ ה-zip של קובצי היעד של מבנה קודם. עבור כל מחיצה ext4 , יש קובץ .map בספריית IMAGES (לדוגמה, IMAGES/system.map מתאים למחיצת system ). לאחר מכן ניתן לבצע צ'ק-אין אלה לקבצי base_fs ולציין אותם באמצעות PRODUCT_<partition>_BASE_FS_PATH , כמו בדוגמה זו:

  PRODUCT_SYSTEM_BASE_FS_PATH := path/to/base_fs_files/base_system.map
  PRODUCT_SYSTEM_EXT_BASE_FS_PATH := path/to/base_fs_files/base_system_ext.map
  PRODUCT_VENDOR_BASE_FS_PATH := path/to/base_fs_files/base_vendor.map
  PRODUCT_PRODUCT_BASE_FS_PATH := path/to/base_fs_files/base_product.map
  PRODUCT_ODM_BASE_FS_PATH := path/to/base_fs_files/base_odm.map

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

הימנע מעדכון אפליקציות

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