Android 9 มีการเปลี่ยนแปลงต่อไปนี้ในข้อกำหนดเกี่ยวกับเหตุผลการเปิดเครื่อง Bootloader
เหตุผลที่เปิดเครื่อง
Bootloader ใช้ฮาร์ดแวร์และทรัพยากรหน่วยความจำที่พร้อมใช้งานที่ไม่ซ้ำกันเพื่อระบุสาเหตุที่อุปกรณ์รีบูต จากนั้นจะแจ้งการตัดสินใจดังกล่าวโดยเพิ่ม 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 ได้ก่อให้เกิดปัญหาในการปฏิบัติตามข้อกำหนดสำหรับ
bootloader_boot_reason_prop
ใน Android 9 ทีม Android ทราบดีว่า bootloader_boot_reason_prop
รุ่นเดิมมีความเคลื่อนไหวอย่างมาก และไม่สามารถเขียนใหม่ระหว่างรันไทม์ได้ ดังนั้น การปรับปรุงข้อกำหนดเฉพาะของเหตุผลในการเปิดเครื่องจะต้องมาจากการโต้ตอบกับนักพัฒนาซอฟต์แวร์ Bootloader และปรับเปลี่ยนระบบที่มีอยู่ ด้วยเหตุนี้ ทีม Android จึงได้ดำเนินการต่อไปนี้
- มีส่วนร่วมกับนักพัฒนาซอฟต์แวร์ Bootloader เพื่อกระตุ้นให้ดำเนินการต่อไปนี้
- ระบุเหตุผล Canonical แยกวิเคราะห์ได้ และเข้าใจได้เพื่อให้
bootloader_boot_reason_prop
- เข้าร่วมในรายการ
system/core/bootstat/bootstat.cpp
kBootReasonMap
.
- ระบุเหตุผล Canonical แยกวิเคราะห์ได้ และเข้าใจได้เพื่อให้
- การเพิ่มแหล่งที่มาที่ควบคุมและเขียนแบบรันไทม์ของ
system_boot_reason_prop
(sys.boot.reason
) ได้ ชุดแอประบบที่จำกัด (เช่นbootstat
และinit
) จะเขียนพร็อพเพอร์ตี้นี้ใหม่ได้ แต่แอปทั้งหมดจะให้สิทธิ์ sepolicy ในการอ่านได้ - แจ้งให้ผู้ใช้ทราบถึงเหตุผลที่เปิดเครื่องให้รอจนกว่าจะต่อเชื่อมข้อมูลผู้ใช้ก่อนที่จะเชื่อถือเนื้อหาในพร็อพเพอร์ตี้เหตุผลเปิดเครื่องของระบบ
system_boot_reason_prop
ทำไมถึงช้าล่ะ แม้ว่า bootloader_boot_reason_prop
จะพร้อมใช้งานตั้งแต่เนิ่นๆ ในการเปิดเครื่อง แต่ก็ถูกบล็อกโดยนโยบายความปลอดภัยของ Android เมื่อจำเป็น เนื่องจากแสดงข้อมูลที่ไม่ถูกต้อง แยกวิเคราะห์ไม่ได้ และไม่ใช่ Canonical
ในกรณีส่วนใหญ่ เฉพาะนักพัฒนาซอฟต์แวร์ที่มีความรู้เชิงลึกเกี่ยวกับระบบการเปิดเครื่องเท่านั้นที่ควรเข้าถึงข้อมูลนี้ Canonical API ที่ปรับแต่ง แยกวิเคราะห์ได้ และ Canonical 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
รูปแบบเหตุผลที่เปิดเครื่องได้
รูปแบบเหตุผลในการเปิดเครื่อง Canonical สำหรับ bootloader_boot_reason_prop
ใน Android 9 ใช้ไวยากรณ์ต่อไปนี้
<reason>,<subreason>,<detail>…
กฎการจัดรูปแบบ
- ตัวพิมพ์เล็ก
- ไม่เว้นวรรค (ใช้ขีดเส้นใต้)
- อักขระที่สามารถพิมพ์ได้ทั้งหมด
- อินสแตนซ์
reason
,subreason
และdetail
ที่คั่นด้วยคอมมาอย่างน้อย 1 รายการreason
ที่จำเป็นซึ่งแสดงถึงเหตุผลที่อุปกรณ์ต้องรีบูตหรือปิดระบบที่มีลำดับความสำคัญสูงสุดsubreason
ที่ไม่บังคับซึ่งแสดงข้อมูลสรุปสั้นๆ เกี่ยวกับสาเหตุที่อุปกรณ์ต้องรีบูตหรือปิดเครื่อง (หรือผู้ที่รีบูตหรือปิดอุปกรณ์)- ค่า
detail
(ไม่บังคับ) อย่างน้อย 1 ค่าdetail
อาจชี้ไปยังระบบย่อยเพื่อช่วยพิจารณาว่าระบบใดส่งผลให้เกิดsubreason
คุณระบุค่าdetail
ได้หลายค่า ซึ่งโดยทั่วไปควรเป็นไปตามลำดับชั้นของความสำคัญ อย่างไรก็ตาม คุณจะรายงานค่าdetail
หลายค่าที่มีความสำคัญเท่ากันได้ด้วย
ค่าว่างสำหรับ bootloader_boot_reason_prop
ถือว่าผิดกฎหมาย (เนื่องจากจะทำให้ Agent อื่นๆ แทรกเหตุผลในการเปิดเครื่องได้หลังจากข้อเท็จจริงแล้ว)
ข้อกำหนดด้านเหตุผล
ค่าที่กำหนดให้สำหรับ reason
(ช่วงแรกก่อนการสิ้นสุดหรือคอมมา) ต้องเป็นค่าต่อไปนี้ที่แบ่งออกเป็น kernel, เหตุผลที่เข้มงวด และเป็นแบบทื่อ
- ชุดเคอร์เนล:
- "
watchdog"
"kernel_panic"
- "
- ชุดข้อมูลที่เหมาะสม
"recovery"
"bootloader"
- ชุดของเทคนิคทื่อ:
"cold"
โดยทั่วไปจะหมายถึงการรีเซ็ตอุปกรณ์ทั้งหมดโดยสมบูรณ์ รวมถึงหน่วยความจำ"hard"
โดยทั่วไปจะระบุว่าฮาร์ดแวร์รีเซ็ตสถานะและramoops
ควรเก็บเนื้อหาไว้อย่างถาวร"warm"
โดยทั่วไปจะระบุหน่วยความจำและอุปกรณ์ ยังคงมีสถานะบางอย่าง และที่เก็บการสนับสนุนramoops
(ดูไดรเวอร์pstore
ในเคอร์เนล) มีเนื้อหาถาวร"shutdown"
"reboot"
โดยทั่วไปหมายความว่าไม่ทราบสถานะramoops
และไม่ทราบสถานะของฮาร์ดแวร์ ค่านี้เป็นค่าที่รับได้ทั้งหมดเนื่องจากค่าcold
,hard
และwarm
จะให้ข้อมูลเกี่ยวกับความลึกของการรีเซ็ตสำหรับอุปกรณ์
Bootloader ต้องมีชุดเคอร์เนลหรือชุด 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
รายงานเหตุผลที่เปิดเครื่อง
เหตุผลที่เปิดเครื่องทั้งหมดไม่ว่าจะมาจาก Bootloader หรือบันทึกไว้ในเหตุผลการเปิดเครื่อง Canonical จะต้องบันทึกในส่วน kBootReasonMap
ของ system/core/bootstat/bootstat.cpp
รายการ kBootReasonMap
มีทั้งเหตุผลที่เป็นไปตามข้อกำหนดและเหตุผลเดิมที่ไม่เป็นไปตามข้อกำหนด นักพัฒนาซอฟต์แวร์ Bootloader ควรลงทะเบียนเฉพาะเหตุผลใหม่ที่เป็นไปตามข้อกำหนดที่นี่ (และไม่ควรลงทะเบียนเหตุผลที่ไม่เป็นไปตามข้อกำหนด เว้นแต่จะมีการจัดส่งผลิตภัณฑ์แล้วและเปลี่ยนแปลงไม่ได้)
เราขอแนะนำให้ใช้รายการที่มีอยู่ซึ่งเป็นไปตามข้อกำหนดใน system/core/bootstat/bootstat.cpp
และใช้การยับยั้งการใช้ก่อนใช้สตริงที่ไม่เป็นไปตามข้อกำหนด ตามหลักเกณฑ์ก็คือ
- ตกลงเพื่อรายงาน
"kernel_panic"
จาก Bootloader เนื่องจากbootstat
อาจตรวจสอบramoops
สำหรับkernel_panic signatures
ได้เพื่อปรับแต่งเหตุผลย่อยใน Canonicalsystem_boot_reason_prop
- ไม่เหมาะสมที่จะรายงานสตริงที่ไม่เป็นไปตามข้อกำหนดใน
kBootReasonMap
(เช่น"panic")
จาก Bootloader เนื่องจากท้ายที่สุดแล้วจะทำให้ความสามารถในการปรับแต่งreason
ใช้ไม่ได้
ตัวอย่างเช่น หาก kBootReasonMap
มี "wdog_bark"
นักพัฒนาซอฟต์แวร์ Bootloader ควรทำดังนี้
- เปลี่ยนเป็น
"watchdog,bark"
และเพิ่มลงในรายการในkBootReasonMap
- ลองพิจารณาว่า
"bark"
มีความหมายอย่างไรสำหรับผู้ที่ไม่คุ้นเคยกับเทคโนโลยีนี้และพิจารณาว่ามีsubreason
ที่มีความหมายมากกว่าหรือไม่
ยืนยันการปฏิบัติตามข้อกำหนดเหตุผลในการเปิดเครื่อง
ขณะนี้ Android ไม่มีการทดสอบ CTS ที่ใช้งานอยู่ซึ่งทริกเกอร์หรือตรวจสอบสาเหตุในการเปิดเครื่องที่เป็นไปได้ทั้งหมดที่ Bootloader ระบุได้อย่างแม่นยำ พาร์ทเนอร์ยังคงพยายามทำการทดสอบแบบแพสซีฟเพื่อระบุความเข้ากันได้ได้
ด้วยเหตุนี้ การปฏิบัติตามข้อกำหนด Bootloader จึงต้องให้นักพัฒนาซอฟต์แวร์ Bootloader ปฏิบัติตามเจตนารมณ์ของกฎและหลักเกณฑ์ที่อธิบายไว้ข้างต้น
เราขอแนะนำให้นักพัฒนาแอปดังกล่าวมีส่วนร่วมใน AOSP (โดยเฉพาะสำหรับ system/core/bootstat/bootstat.cpp
) และใช้โอกาสนี้เป็นฟอรัมสำหรับการสนทนาเกี่ยวกับปัญหาสาเหตุในการเปิดเครื่อง