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