เหตุผลในการบูต Canonical

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 เพื่อปรับแต่งเหตุผลย่อยลงใน canonical system_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 ) และใช้โอกาสนี้เป็นฟอรัมสำหรับการอภิปรายเกี่ยวกับปัญหาเหตุผลในการบู๊ต