Android 9 มีการเปลี่ยนแปลงต่อไปนี้ในข้อกำหนดเหตุผลในการบูต 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
รุ่นเก่ามีแรงผลักดันที่สำคัญและไม่สามารถเขียนใหม่ได้ในขณะรันไทม์ การปรับปรุงข้อกำหนดเหตุผลในการบูตจึงต้องมาจากการโต้ตอบกับนักพัฒนาโปรแกรมโหลดบูตและการปรับแต่งระบบที่มีอยู่ ด้วยเหตุนี้ ทีมงาน Android คือ:
- มีส่วนร่วมกับนักพัฒนา Bootloader เพื่อสนับสนุนให้พวกเขา:
- ระบุเหตุผลที่เป็นที่ยอมรับ สามารถแยกวิเคราะห์ได้ และจดจำได้ให้กับ
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
รูปแบบเหตุผลการบูตตาม Canonical
รูปแบบเหตุผลการบูตตามรูปแบบบัญญัติสำหรับ 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
จะให้เบาะแสเกี่ยวกับความลึกของการรีเซ็ตอุปกรณ์
-
Bootloaders ต้องระบุชุดเคอร์เนลหรือ 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 หรือบันทึกไว้ในเหตุผลการบู๊ตตามรูปแบบบัญญัติ จะต้องถูกบันทึกไว้ในส่วน 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 ต้องปฏิบัติตามเจตนารมณ์ของกฎและแนวปฏิบัติที่อธิบายไว้ข้างต้นโดยสมัครใจ เราขอแนะนำให้นักพัฒนาดังกล่าวสนับสนุน AOSP (โดยเฉพาะกับ system/core/bootstat/bootstat.cpp
) และใช้โอกาสนี้เป็นฟอรัมสำหรับการอภิปรายเกี่ยวกับปัญหาเหตุผลในการบู๊ต