סיבת האתחול הקנונית

מערכת Android 9 כוללת את השינויים הבאים במפרט הסיבה להפעלה של תוכנת האתחול.

הסיבות להפעלה

תוכנת אתחול משתמשת במשאבי חומרה וזיכרון שזמינים באופן ייחודי כדי לקבוע למה המכשיר הופעל מחדש, ואז מדווחת על כך על ידי הוספת androidboot.bootreason=<reason> לשורת הפקודה בליבה (kernel) של Android לצורך ההפעלה. לאחר מכן, init מתרגמת את שורת הפקודה הזו להפצה של נכס Android bootloader_boot_reason_prop (ro.boot.bootreason). במכשירים שפועלת עם Android מגרסה 12 ואילך, שמותקנת בהם גרסת ליבה (kernel) 5.10 ואילך, המערכת מוסיפה את androidboot.bootreason=<reason> ל-אתחול במקום שורת הפקודה בליבה (kernel).

מפרטים של הסיבות להפעלה

בגרסאות הקודמות של Android צוין פורמט של סיבה להפעלה שלא נעשה בו שימוש ברווחים. הפורמט כלל אותיות קטנות, כולל כמה דרישות (למשל: דיווח kernel_panic, watchdog, cold/warm/hard) ושכלולות בקשות מסיבות ייחודיות אחרות. המפרט החופשי הזה גרם לעלייה של מאות מחרוזות של סיבות הפעלה בהתאמה אישית (ולפעמים חסרות משמעות), שהובילו למצב שלא ניתן לנהל. נכון לגרסה הנוכחית של Android, המומנטום של תוכן כמעט בלתי ניתן לניתוח או חסר משמעות שנשלח על ידי תוכנת האתחול יצר בעיות תאימות עבור bootloader_boot_reason_prop.

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

  • אינטראקציה עם מפתחי תוכנת אתחול ולעודד אותם:
    • צריך לציין סיבות קנוניות, ניתנות לניתוח וניתנות לזיהוי ל-bootloader_boot_reason_prop.
    • רוצה להשתתף ברשימה system/core/bootstat/bootstat.cpp של kBootReasonMap?
  • הוספת מקור מבוקר שניתן לכתיבה בזמן ריצה של system_boot_reason_prop (sys.boot.reason). קבוצה מוגבלת של אפליקציות מערכת (כמו bootstat ו-init) יכולות לשכתב את המאפיין הזה, אבל אפשר לתת לכל האפליקציות הרשאות לקרוא אותו באמצעות מדיניות.
  • הודעה למשתמשים לגבי סיבת ההפעלה שצריך להמתין עד אחרי טעינת נתוני המשתמש לפני שסומכים על התוכן במאפיין סיבת ההפעלה של המערכת system_boot_reason_prop.

למה כל כך מאוחר? bootloader_boot_reason_prop זמינה בשלב מוקדם בהפעלה, אבל היא חסומה על ידי מדיניות האבטחה של Android לפי הצורך, כי היא מייצגת מידע לא מדויק, לא ניתן לניתוח ולא קנוני. ברוב המקרים, רק מפתחים עם ידע מעמיק על מערכת ההפעלה צריכים לגשת למידע הזה. ניתן להגדיר API מעודן, ניתן לניתוח וקנוני עקב סיבת ההפעלה עם system_boot_reason_prop באופן מהימן ולאסוף באופן מדויק רק אחרי נתוני המשתמש. פרטים נוספים:

  • לפני הטעינה של נתוני המשתמשים, הפרמטר system_boot_reason_prop יכיל את הערך מהערך bootloader_boot_reason_prop.
  • אחרי הטעינה של נתוני המשתמשים, יכול להיות שיתבצע עדכון של system_boot_reason_prop כדי לעמוד בדרישות או כדי לדווח על מידע מדויק יותר.

מהסיבה הזו, מערכת Android 9 מאריכה את פרק הזמן שעד אליו ניתן להשיג את סיבת ההפעלה באופן רשמי, ומשנה אותה ממדויקת יותר בהפעלה (עם bootloader_boot_reason_prop) כך שיהיה זמין רק לאחר טעינה של נתוני המשתמש (עם system_boot_reason_prop).

לוגיקת ההפעלה תלויה ב-bootloader_boot_reason_prop אינפורמטיבי ותואם יותר. כשהמאפיין משתמש בפורמט צפוי, הוא משפר את הדיוק של כל תרחישי ההפעלה והכיבוי מבוקרים. כתוצאה מכך, המערכת משפרת ומרחיבה את הדיוק והמשמעות של system_boot_reason_prop.

פורמט קנוני של סיבת האתחול

הפורמט של סיבת ההפעלה הקנונית של bootloader_boot_reason_prop ב-Android 9 כולל את התחביר הבא:

<reason>,<subreason>,<detail>…

עיצוב כללים:

  • אותיות קטנות
  • ללא דפים ריקים (שימוש בקו תחתון)
  • כל התווים שאפשר להדפיס
  • reason ו-subreason שמופרדים בפסיקים ומופע אחד או יותר של detail.
    • ערך נדרש מסוג reason שמייצג את הסיבה בעדיפות הגבוהה ביותר שבגללה היה צורך להפעיל מחדש או לכבות את המכשיר.
    • subreason אופציונלי שמייצג סיכום קצר של הסיבות שבגללן היה צריך להפעיל מחדש או לכבות את המכשיר (או מי הפעיל מחדש או כיבה את המכשיר).
    • אחד או יותר מהערכים של השדה detail אופציונלי. detail יכול להפנות למערכת משנה כדי לקבוע איזו מערכת ספציפית הובילה ל-subreason. אפשר לציין כמה ערכי detail, שבדרך כלל צריכים להיות לפי היררכיה של חשיבות. עם זאת, אפשר גם לדווח על כמה ערכי detail בעלי חשיבות זהה.

ערך ריק של bootloader_boot_reason_prop נחשב לא חוקי (מכיוון שכך סוכנים אחרים יכולים להזריק סיבת הפעלה לאחר מעשה).

דרישות לסיבות

הערך שניתן ל-reason (טווח ראשון, לפני הסיום או פסיק) חייב להיות מהקבוצה הבאה ולחלק לסיבות ליבה, חזקות וקהות:

  • הגדרת הליבה:
    • watchdog"
    • "kernel_panic"
  • קבוצה חזקה:
    • "recovery"
    • "bootloader"
  • הגדרה קהה:
    • "cold". מציין בדרך כלל איפוס מלא של כל המכשירים, כולל זיכרון.
    • "hard". המשמעות היא באופן כללי, שהמצב של החומרה מתאפס ו-ramoops צריך לשמור תוכן קבוע.
    • "warm". מציין באופן כללי שהזיכרון והמכשירים שומרים מצב מסוים, ומאגר הגיבוי של ramoops (מידע נוסף זמין במנהל התקן pstore בליבה) מכיל תוכן קבוע.
    • "shutdown"
    • "reboot". בדרך כלל המשמעות היא שהמצב ramoops לא ידוע ומצב החומרה לא ידוע. הערך הזה הוא כללי, כי הערכים cold, hard ו-warm מספקים רמזים לגבי עומק האיפוס של המכשיר.

תוכנות אתחול חייבות לספק הגדרת ליבה או קבוצה קהה reason, ומומלץ מאוד לספק subreason אם ניתן לקבוע זאת. לדוגמה, לחיצה ארוכה על מקש הפעלה עם גיבוי של ramoops, גם אם לא, תגרום לסיבת האתחול "reboot,longkey".

reason לא יכול להיות חלק מ-subreason או מ-detail. עם זאת, מכיוון שמרחב המשתמש לא יכול לייצר את הסיבות להגדרת הליבה, ניתן לעשות שימוש חוזר ב-"watchdog" אחרי סיבה קהה, יחד עם פירוט של המקור (לדוגמה, "reboot,watchdog,service_manager_unresponsive" או "reboot,software,watchdog").

סיבות ההפעלה לא צריכות לדרוש ידע פנימי של מומחה כדי לפענח אותן ו/או שהן צריכות להיות מנוסחות באופן קריא לאנשים עם דוח אינטואיטיבי. דוגמאות: "shutdown,vbxd" (גרועה), "shutdown,uv" (טוב יותר), "shutdown,undervoltage" (מועדף).

שילובים של סיבה משנית

Android שומר קבוצה של שילובים של reason-subreason שאסור להעמיס מדי בשימוש רגיל, אבל אפשר להשתמש בהם על בסיס כל מקרה לגופו, אם השילוב משקף במדויק את התנאי המשויך. דוגמאות לשילובים שמורים:

  • "reboot,userrequested"
  • "shutdown,userrequested"
  • "shutdown,thermal" (החל מ-thermald)
  • "shutdown,battery"
  • "shutdown,battery,thermal" (החל מ-BatteryStatsService)
  • "reboot,adb"
  • "reboot,shell"
  • "reboot,bootloader"
  • "reboot,recovery"

לפרטים נוספים, אפשר לעיין ב-kBootReasonMap ב-system/core/bootstat/bootstat.cpp ובהיסטוריית יומן השינויים של Git המשויכת במאגר המקור של Android.

דיווח על סיבות הפעלה

יש לתעד את כל הסיבות להפעלה, מתוכנת האתחול או מהסיבה שנרשמה בסיבת ההפעלה הקנונית, בקטע kBootReasonMap של system/core/bootstat/bootstat.cpp. הרשימה kBootReasonMap כוללת שילוב של סיבות שקשורות לתאימות ולבעיות מדור קודם שלא עומדות בדרישות. מפתחים של תוכנת אתחול צריכים לרשום כאן רק סיבות חדשות שקשורות לתאימות (ואסור להם לרשום סיבות שלא תואמות למדיניות, אלא אם המוצר כבר נשלח ואי אפשר לשנות אותו).

מומלץ מאוד להשתמש בערכים קיימים שעומדים בדרישות של system/core/bootstat/bootstat.cpp ולהקפיד על הגבלה לפני השימוש במחרוזת שלא תואמת. ההנחיות הן:

  • אפשר לדווח על "kernel_panic" מתוכנת האתחול, כי bootstat יכול להיות שתהיה ל-bootstat אפשרות לבדוק את ramoops עבור kernel_panic signatures כדי לצמצם את תתי-הסיבות ל-system_boot_reason_prop הקנוני.
  • לא בסדר לדווח על מחרוזת שלא תואמת למדיניות ב-kBootReasonMap (למשל "panic") מתוכנת האתחול, כי הפעולה הזו תפגע בסופו של דבר את היכולת לשפר את reason.

לדוגמה, אם הערך kBootReasonMap מכיל את הערך "wdog_bark", מפתח תוכנת אתחול צריך:

  • אפשר לשנות את התפקיד ל-"watchdog,bark" ולהוסיף לרשימה בkBootReasonMap.
  • כדאי לחשוב מה המשמעות של "bark" למשתמשים שלא מכירים את הטכנולוגיה ולקבוע אם קיימת subreason משמעותית יותר.

בדיקת התאימות של סיבת ההפעלה

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

כתוצאה מכך, כדי לעמוד בדרישות של תוכנת האתחול, מפתחי תוכנת האתחול צריכים לפעול בהתאם לרוח הכללים וההנחיות שתוארו למעלה. אנחנו ממליצים למפתחים כאלה לתרום ל-AOSP (במיוחד ל-system/core/bootstat/bootstat.cpp) ולהשתמש בהזדמנות הזו כפורום לדיונים על בעיות בסיבות להפעלה.