Android 9 כולל את השינויים הבאים במפרט של סיבות האתחול של מנהל האתחול.
הסיבות להפעלה
תוכנת אתחול משתמשת במשאבי חומרה וזיכרון שזמינים באופן ייחודי כדי לקבוע למה המכשיר הופעל מחדש, ואז מדווחת על כך על ידי הוספת androidboot.bootreason=<reason>
לשורת הפקודה בליבה (kernel) של 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
) יכולות לשכתב את המאפיין הזה, אבל אפשר לתת לכל האפליקציות הרשאות לקרוא אותו באמצעות מדיניות. - להודיע למשתמשים על סיבה לאתחול ולבקש מהם להמתין עד שמתקינים את userdata לפני שהם נותנים אמון בתוכן במאפיין של סיבה לאתחול המערכת
system_boot_reason_prop
.
למה זה קורה כל כך מאוחר? bootloader_boot_reason_prop
זמינה בשלב מוקדם
בהפעלה, אבל היא חסומה על ידי מדיניות האבטחה של Android לפי הצורך, כי היא מייצגת מידע לא מדויק, לא ניתן לניתוח ולא קנוני.
ברוב המקרים, רק מפתחים עם ידע מעמיק על מערכת ההפעלה
צריכים לגשת למידע הזה. אפשר לזהות באופן מהימן ומדויק API משופר, שניתן לנתח ולעבד, של הסיבה להפעלה באמצעות system_boot_reason_prop
רק אחרי הטעינה של userdata.
פרטים נוספים:
- לפני הטעינה של נתוני המשתמשים,
הפרמטר
system_boot_reason_prop
יכיל את הערך מהערךbootloader_boot_reason_prop
. - אחרי הרכבת userdata, יכול להיות ש-
system_boot_reason_prop
יתעדכן כדי לעמוד בדרישות או כדי לדווח על מידע מדויק יותר.
לכן, בגרסה 9 של Android הזמן שבו אפשר לקבל באופן רשמי את הסיבה להפעלה הוא ארוך יותר. במקום שהיא תהיה זמינה מיד אחרי ההפעלה (עם bootloader_boot_reason_prop
), היא זמינה רק אחרי שמתקינים את userdata (עם 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:
"cold"
. מציין בדרך כלל איפוס מלא של כל המכשירים, כולל זיכרון."hard"
. בדרך כלל מציין שהמצב של החומרה אפס, ו-ramoops
אמור לשמור תוכן קבוע."warm"
. בדרך כלל מציין שהזיכרון והמכשירים שומרים מצב כלשהו, ושאחסון ה-back-end של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"
לאנשים שלא מכירים את הטכנולוגיה, ולבדוק אם יש"bark"
משמעותי יותר שזמין.subreason
בדיקת התאימות של סיבת ההפעלה
נכון לעכשיו, Android לא מספק בדיקת CTS פעילה שיכולה להפעיל או לבדוק בצורה מדויקת את כל הסיבות האפשריות להפעלה של מנהל האתחול. עם זאת, השותפים עדיין יכולים לנסות להריץ בדיקה פסיבית כדי לקבוע את התאימות.
כתוצאה מכך, כדי לעמוד בדרישות התאימות של תוכנת האתחול, מפתחי תוכנת האתחול צריכים לפעול מרצונם בהתאם לרוח הכללים וההנחיות שמפורטים למעלה.
אנחנו ממליצים למפתחים כאלה לתרום ל-AOSP (במיוחד ל-system/core/bootstat/bootstat.cpp
) ולהשתמש בהזדמנות הזו כפורום לדיון בבעיות שקשורות לגורם האתחול.