Android 9 כוללת את השינויים הבאים במפרט של סיבת ההפעלה של טוען האתחול.
סיבות להפעלה
טוען האתחול משתמש במשאבי חומרה וזיכרון שזמינים באופן ייחודי כדי לקבוע למה המכשיר הופעל מחדש, ואז הוא מוסיף את androidboot.bootreason=<reason>
לשורת הפקודה של ליבת Android כדי להעביר את ההחלטה הזו. init
ואז מתרגם את שורת הפקודה הזו כדי להפיץ אותה למאפיין Android bootloader_boot_reason_prop
(ro.boot.bootreason
). במכשירים עם Android מגרסה 12 ואילך, שמופעלים עם ליבה בגרסה 5.10 ואילך, androidboot.bootreason=<reason>
נוסף ל-bootconfig במקום לשורת הפקודה של הליבה.
מפרטים של סיבת ההפעלה
בגרסאות קודמות של 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
) יכולה לשכתב את המאפיין הזה, אבל אפשר להעניק לכל האפליקציות הרשאות sepolicy לקריאת המאפיין. - הודעה למשתמשים על סיבת האתחול כדי להמתין עד להרכבת נתוני המשתמש
לפני שסומכים על התוכן במאפיין סיבת האתחול של המערכת
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
).
הלוגיקה של Bootstat תלויה ב-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"
- blunt set:
-
"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
כוללת סיבות שעומדות בדרישות וסיבות מדור קודם שלא עומדות בדרישות. מפתחי Bootloader צריכים לרשום כאן רק סיבות חדשות לתאימות (ואסור לרשום סיבות לאי-תאימות אלא אם המוצר כבר נשלח ואי אפשר לשנות אותו).
מומלץ מאוד להשתמש ברשומות קיימות ועומדות בדרישות ב-system/core/bootstat/bootstat.cpp
ולהימנע משימוש במחרוזת שלא עומדת בדרישות. ככלל, הוא:
- OK כדי לדווח על
"kernel_panic"
מ-bootloader, כי יכול להיות ש-bootstat
יוכל לבדוק אתramoops
כדי לחדד את הסיבות המשניות ל-kernel_panic signatures
ל-system_boot_reason_prop
קנוני. - לא מומלץ לדווח על מחרוזת לא תואמת ב-
kBootReasonMap
(למשל"panic")
מ-bootloader), כי זה יפגע בסופו של דבר ביכולת לשפר אתreason
.
לדוגמה, אם kBootReasonMap
מכיל את "wdog_bark"
,
מפתח של bootloader צריך:
- מעבר ל
"watchdog,bark"
והוספה לרשימה בkBootReasonMap
. - כדאי להסביר מה זה
"bark"
למי שלא מכיר את הטכנולוגיה, ולבדוק אם ישsubreason
משמעותי יותר.
אימות התאימות של סיבת האתחול
בשלב הזה, מערכת Android לא מספקת בדיקת CTS פעילה שיכולה להפעיל או לבדוק בצורה מדויקת את כל הסיבות האפשריות להפעלה שמטען האתחול יכול לספק. שותפים עדיין יכולים לנסות להפעיל בדיקה פסיבית כדי לקבוע תאימות.
לכן, כדי שה-bootloader יעמוד בדרישות, מפתחי ה-bootloader צריכים לפעול בהתאם לרוח הכללים וההנחיות שמתוארים למעלה.
אנחנו קוראים למפתחים כאלה לתרום ל-AOSP (ספציפית ל-system/core/bootstat/bootstat.cpp
) ולנצל את ההזדמנות הזו כפורום לדיונים בנושא בעיות שקשורות לסיבת האתחול.