הטמעת אתחול ב-Android 12

ב-Android 12, התכונה bootconfig מחליפה את האפשרויות של androidboot.* kernel cmdline שנמצאות בשימוש ב-Android 11 ובגרסאות קודמות. התכונה bootconfig היא מנגנון להעברת פרטי הגדרה מה-build ומטוען האתחול אל Android 12.

התכונה הזו מאפשרת להפריד בין פרמטרים של הגדרות למרחב המשתמש ב-Android לבין פרמטרים של הגדרות לליבה. העברת הפרמטרים הארוכים של ליבת androidboot.* לקובץ bootconfig מפנה מקום בשורת הפקודה של הליבה, והופכת אותו לזמין להרחבה עתידית.

גם הליבה וגם מרחב המשתמש של Android צריכים לתמוך ב-bootconfig.

  • הגרסה הראשונה שכוללת את התמיכה הזו: Android 12
  • גרסת הליבה הראשונה שבה יש תמיכה: ליבה 12-5.4.xx

הטמענו את התכונה bootconfig במכשירים חדשים שמופעלים עם גרסת ליבה 12-5.10.xx. אין צורך להטמיע את התכונה הזו אם משדרגים את המכשירים.

דוגמאות ומקור

כשמעיינים בדוגמאות ובקוד המקור בקטע הזה, חשוב לשים לב שהפורמט של קוד bootconfig שונה רק במעט מהפורמט של שורת הפקודה של ליבת מערכת ההפעלה שמשמשת ב-Android 11 ובגרסאות קודמות. עם זאת, חשוב להכיר את ההבדל הבא:

  • צריך להפריד בין הפרמטרים באמצעות רצף בריחה של שורה חדשה \n, ולא באמצעות רווחים.

דוגמה לתוכנת אתחול

דוגמה לטוען אתחול אפשר לראות בטוען האתחול של Cuttlefish U-boot. שני קומיטים בהפניה מפורטים בהמשך. הראשון מעדכן את התמיכה בגרסת כותרת האתחול לגרסה העדכנית ביותר. בדוגמה, העדכון הראשון (או העדכון לגרסה מתקדמת יותר) של הקומיט הוא לגרסה הבאה, v4. הפקודה השנייה עושה שני דברים: היא מוסיפה טיפול ב-bootconfig ומדגימה הוספה של פרמטרים בזמן ריצה:

דוגמה ל-build

דוגמה לבנייה שבה מוצגים שינויים ב-mkbootimg כדי לבנות את vendor_boot.img עם כותרת אתחול של ספק בגרסה 4 זמינה במאמר mkbootimg changes for bootconfig. כדי לבצע את הפעולות הבאות, אפשר לעיין בשינויים ב-Cuttlefish:

הטמעה

השותפים צריכים להוסיף תמיכה לטועני האתחול שלהם ולהעביר את הפרמטרים של androidboot.* בזמן הבנייה מקובץ cmdline של ליבת המערכת לקובץ bootconfig. הדרך הכי טובה להטמיע את השינוי הזה היא לעשות זאת באופן הדרגתי. בקטע הטמעה ואימות הדרגתיים מוסבר איך לבצע את התהליך הזה.

אם יש לכם שינויים שמחפשים פרמטרים בקובץ ‎ /proc/cmdline, צריך להפנות אותם לקובץ /proc/bootconfig במקום זאת.androidboot.* המאפיינים ro.boot.* מוגדרים עם הערכים החדשים bootconfig, כך שלא צריך לבצע שינויים בקוד שמשתמש במאפיינים האלה.

שינויים בבנייה

קודם כול, מעלים את הגרסה של כותרת האתחול לגרסה 4:

- BOARD_BOOT_HEADER_VERSION := 3

+ BOARD_BOOT_HEADER_VERSION := 4

מוסיפים את הפרמטר bootconfig של שורת הפקודה של ליבת המערכת. כך הליבה מחפשת את הקטע bootconfig:

BOARD_KERNEL_CMDLINE += bootconfig

הפרמטרים של bootconfig נוצרים מהפרמטרים במשתנה BOARD_BOOTCONFIG, בדומה לאופן שבו נוצר kernel cmdline מ-BOARD\_KERNEL\_CMDLINE.

אפשר להעביר כל פרמטר androidboot.* כמו שהוא, באופן הבא:

- BOARD_KERNEL_CMDLINE += androidboot..selinux=enforcing

+ BOARD_BOOTCONFIG += androidboot..selinux=enforcing

שינויים בתוכנת האתחול

טוען האתחול מגדיר את initramfs לפני שהוא עובר לליבת המערכת. ההגדרה של אתחול הליבה מחפשת את הקטע bootconfig, ומוודאת שהוא נמצא בסוף הקובץ initramfs, עם הטריילר הצפוי.

טוען האתחול מקבל את פרטי הפריסה של vendor_boot.img מכותרת תמונת האתחול של הספק.

תרשים של פריסת הקצאת הזיכרון של bootconfig

איור 1. הקצאת זיכרון ב-bootconfig ב-Android 12

טוען האתחול יוצר את הקטע bootconfig בזיכרון. הקטע bootconfig מכיל הקצאות זיכרון לפריטים הבאים:

  • פרמטרים
  • ‫4 B size parameters size
  • ‫4 B size parameters checksum
  • מחרוזת קסם של 12 B bootconfig ‏ (#BOOTCONFIG\n)

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

פרמטרים שידועים בזמן ה-build נארזים בסוף vendor_bootהתמונה בקטע bootconfig. גודל הקטע מאוחסן (בבייטים) בשדה vendor_bootconfig_size בכותרת האתחול של הספק.

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

אם צריך להוסיף פרמטרים אחרי החלת ה-trailer של bootconfig, צריך להחליף את ה-trailer ולהחיל אותו מחדש.

הטמעה ואימות מצטברים

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

אלה השלבים להטמעה מצטברת, עם אימות:

  1. יוצרים את טוען האתחול ומבצעים שינויים ב-build, ואז מבצעים את הפעולות הבאות:
    1. משתמשים במשתנה BOARD_BOOTCONFIG כדי להוסיף פרמטר חדש של bootconfig.
    2. חשוב להשאיר את הפרמטרים של שורת הפקודה של ליבת המערכת כמו שהם, כדי שהמכשיר יוכל להמשיך לאתחל את עצמו בצורה תקינה. כך קל יותר לבצע ניפוי באגים ואימות.
  2. מאמתים את העבודה על ידי בדיקת התוכן של /proc/bootconfig. מוודאים שהפרמטר החדש שנוסף מופיע אחרי שהמכשיר מופעל.
  3. מעבירים את הפרמטרים androidboot.* משורת הפקודה של ליבת המערכת אל bootconfig, באמצעות המשתנה BOARD_BOOTCONFIG וטוען האתחול.
  4. מוודאים שכל אחד מהפרמטרים מופיע ב-/proc/bootconfig ושהם לא מופיעים ב-/proc/cmdline. אם אתם יכולים לאמת את זה, ההטמעה שלכם בוצעה בהצלחה.

שיקולים לגבי שדרוג ושדרוג לאחור של OTA

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

‫Android 12 היא הגרסה הראשונה עם תמיכה ב-bootconfig. אם מבצעים שדרוג לאחור לגרסה כלשהי שלפני כן, צריך להשתמש בפרמטרים של שורת הפקודה של הליבה במקום ב-bootconfig.

גרסאות ליבה 12-5.4 ואילך תומכות ב-bootconfig. אם מבצעים שדרוג לאחור לגרסה כלשהי שקודמת לגרסה הזו(כולל 11-5.4), צריך להשתמש בפרמטרים של שורת הפקודה של הליבה.

במכשירים שמשודרגים מ-Android 11 ומגרסאות מוקדמות יותר ל-Android 12 ומגרסאות מאוחרות יותר, אפשר להמשיך להשתמש בפרמטרים של שורת הפקודה של ליבת המערכת. אותו עיקרון חל גם על שדרוג גרסאות הליבה.

פתרון בעיות

כשמבצעים את שלב האימות, אם הפרמטרים הצפויים לא מופיעים ב-/proc/bootconfig, צריך לבדוק את יומני הליבה ב-logcat. תמיד יש רשומה ביומן עבור bootconfig אם הליבה תומכת בה.

פלט לדוגמה של יומן

$ adb logcat | grep bootconfig
02-24 17:00:07.610     0     0 I Load bootconfig: 128 bytes 9 nodes

אם מוחזר יומן שגיאות, הייתה בעיה בטעינת bootconfig. כדי לראות סוגים שונים של שגיאות, אפשר לעיין בקובץ init/main.c.