เหตุผลที่เปิดเครื่องได้

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 จะบล็อก bootloader_boot_reason_prop ตามความจำเป็นเนื่องจากแสดงข้อมูลที่ไม่เป็นความจริง ไม่สามารถแยกวิเคราะห์ได้ และไม่ถูกต้อง ในสถานการณ์ส่วนใหญ่ มีเพียงนักพัฒนาซอฟต์แวร์ที่มีความเชี่ยวชาญด้านระบบบูตเท่านั้นที่ควรเข้าถึงข้อมูลนี้ได้ API สำหรับเหตุผลในการบูตที่มี system_boot_reason_prop ที่ปรับแต่งแล้ว แยกวิเคราะห์ได้ และตามมาตรฐานจะได้รับการแยกออกอย่างถูกต้องและเชื่อถือได้หลังจากการต่อเชื่อม userdata แล้วเท่านั้น ดังนี้

  • ก่อนทำการต่อเชื่อมข้อมูลผู้ใช้ โดย system_boot_reason_prop จะมีค่าจาก bootloader_boot_reason_prop
  • หลังจากใส่ข้อมูลผู้ใช้แล้ว ระบบอาจอัปเดต system_boot_reason_prop เพื่อให้เป็นไปตามข้อกําหนดหรือเพื่อรายงานข้อมูลที่แม่นยํายิ่งขึ้น

ด้วยเหตุนี้ Android 9 จึงขยายระยะเวลาก่อนที่จะรับเหตุผลการบูตอย่างเป็นทางการ ซึ่งเปลี่ยนจากข้อมูลที่ถูกต้องทันทีในการบูต (ใช้ 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 อย่างน้อย 1 รายการที่คั่นด้วยคอมมา
    • reason ที่จำเป็นซึ่งแสดงถึงเหตุผลที่อุปกรณ์ต้องรีบูตหรือปิดระบบที่มีลำดับความสำคัญสูงสุด
    • subreason (ไม่บังคับ) ที่แสดงข้อมูลสรุปสั้นๆ เกี่ยวกับสาเหตุที่อุปกรณ์ต้องรีบูตหรือปิดเครื่อง (หรือผู้ที่รีบูตหรือปิดเครื่อง)
    • ค่า detail อย่างน้อย 1 ค่า (ไม่บังคับ) 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 ให้เบาะแสเกี่ยวกับระดับการรีเซ็ตอุปกรณ์

บูตโหลดเดอร์ต้องระบุชุดเคอร์เนลหรือชุด Blunt 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 ได้เพื่อปรับแต่งเหตุผลย่อยใน Canonical system_boot_reason_prop
  • ใช้ไม่ได้ในการรายงานสตริงที่ไม่เป็นไปตามข้อกำหนดใน kBootReasonMap (เช่น "panic") จาก Bootloader เนื่องจากท้ายที่สุดแล้วจะทำให้ความสามารถในการปรับแต่ง reason ใช้ไม่ได้

ตัวอย่างเช่น หาก kBootReasonMap มี "wdog_bark" นักพัฒนาซอฟต์แวร์ Bootloader ควรทำดังนี้

  • เปลี่ยนเป็น "watchdog,bark" และเพิ่มลงในรายการใน kBootReasonMap
  • พิจารณาว่า "bark" หมายถึงอะไรสำหรับผู้ที่ไม่คุ้นเคยกับเทคโนโลยี และพิจารณาว่า subreason ที่สื่อความหมายมากกว่ามีหรือไม่

ยืนยันการปฏิบัติตามข้อกำหนดเหตุผลในการเปิดเครื่อง

ขณะนี้ Android ไม่มีการทดสอบ CTS ที่ใช้งานอยู่ซึ่งทริกเกอร์หรือตรวจสอบสาเหตุในการเปิดเครื่องที่เป็นไปได้ทั้งหมดที่ Bootloader ระบุได้อย่างแม่นยำ พาร์ทเนอร์ยังคงพยายามทำการทดสอบแบบแพสซีฟเพื่อระบุความเข้ากันได้ได้

ด้วยเหตุนี้ การปฏิบัติตามข้อกำหนดของบูตโหลดเดอร์จึงกำหนดให้นักพัฒนาบูตโหลดเดอร์ต้องปฏิบัติตามเจตนารมณ์ของกฎและหลักเกณฑ์ที่อธิบายไว้ข้างต้นด้วยความสมัครใจ เราขอแนะนำให้นักพัฒนาแอปดังกล่าวมีส่วนร่วมใน AOSP (โดยเฉพาะใน system/core/bootstat/bootstat.cpp) และใช้โอกาสนี้ในฟอรัมเพื่อพูดคุยเกี่ยวกับปัญหาเกี่ยวกับเหตุผลในการบูต