Lý do khởi động theo chuẩn

Android 9 có các thay đổi sau đây đối với quy cách về lý do khởi động của trình tải khởi động.

Lý do khởi động

Trình tải khởi động sử dụng các tài nguyên phần cứng và bộ nhớ có sẵn duy nhất để xác định lý do thiết bị khởi động lại, sau đó truyền đạt quyết định đó bằng cách đang thêm androidboot.bootreason=<reason> vào Android dòng lệnh kernel để khởi chạy. init sau đó dịch nội dung này để phổ biến cho thuộc tính Android bootloader_boot_reason_prop (ro.boot.bootreason). Đối với các thiết bị chạy Android 12 trở lên, sử dụng kernel phiên bản 5.10 trở lên, androidboot.bootreason=<reason> được thêm vào bootconfig thay vì dòng lệnh kernel.

Thông số kỹ thuật về lý do khởi động

Các bản phát hành Android trước đây đã chỉ định một định dạng lý do khởi động sử dụng dấu cách, đều là chữ thường, kèm theo một số yêu cầu (chẳng hạn như đối với tính năng báo cáo kernel_panic, watchdog cold/warm/hard) và đã tạo ra vì các lý do riêng biệt khác. Quy cách lỏng lẻo này dẫn đến việc sự tăng vọt của hàng trăm lý do khởi động tuỳ chỉnh (và đôi khi vô nghĩa) do đó dẫn đến tình huống không thể quản lý được. Tính đến hiện tại Bản phát hành Android, động lượng tuyệt đối của nội dung gần như không thể phân tích cú pháp hoặc vô nghĩa do trình tải khởi động gửi đã gây ra các vấn đề về tuân thủ đối với bootloader_boot_reason_prop.

Với bản phát hành Android 9, đội ngũ Android nhận ra rằng bootloader_boot_reason_prop cũ đã động lượng đáng kể và không thể viết lại trong thời gian chạy. Mọi điểm cải tiến đối với do đó, thông số kỹ thuật về lý do khởi động phải đến từ hoạt động tương tác với cho nhà phát triển trình tải khởi động và chỉnh sửa hệ thống hiện có. Để đạt được mục tiêu này, Nhóm Android:

  • Tương tác với các nhà phát triển trình tải khởi động để khuyến khích họ:
    • Nêu các lý do chính tắc, có thể phân tích cú pháp và dễ nhận dạng để bootloader_boot_reason_prop.
    • Tham gia system/core/bootstat/bootstat.cpp Danh sách kBootReasonMap.
  • Thêm nguồn được kiểm soát và có thể ghi trong thời gian chạy của system_boot_reason_prop (sys.boot.reason). Đáp một số ứng dụng hệ thống (chẳng hạn như bootstatinit) có thể viết lại thuộc tính này, nhưng tất cả ứng dụng đều có thể được cấp quyền sepolicy để đọc nó.
  • Thông báo cho người dùng về lý do khởi động phải đợi cho đến khi dữ liệu người dùng được kết nối trước khi tin tưởng nội dung trong thuộc tính lý do khởi động hệ thống system_boot_reason_prop.

Sao lại trễ đến thế? Mặc dù bootloader_boot_reason_prop có sẵn từ sớm khi khởi động, ứng dụng sẽ bị chặn bởi chính sách bảo mật của Android trên cơ sở nhu cầu vì nó biểu thị thông tin không chính xác, không thể phân tích cú pháp và không chuẩn. Trong hầu hết các trường hợp, chỉ những nhà phát triển có kiến thức sâu rộng về hệ thống khởi động cần truy cập thông tin này. Một URL chuẩn, có thể phân tích cú pháp và được tinh chỉnh API vì lý do khởi động với system_boot_reason_prop có thể đáng tin cậy và chỉ nhận được chính xác sau khi dữ liệu người dùng được gắn kết. Cụ thể:

  • Trước khi dữ liệu người dùng được gắn kết, system_boot_reason_prop sẽ chứa giá trị từ bootloader_boot_reason_prop.
  • Sau khi dữ liệu người dùng được gắn kết, system_boot_reason_prop có thể được cập nhật để tuân thủ hoặc để báo cáo thông tin chính xác hơn.

Vì lý do này, Android 9 kéo dài thời gian trước khi có thể có được lý do khởi động chính thức, thay đổi lý do này thành chính xác ngay lập tức khi khởi động (với bootloader_boot_reason_prop) chỉ có sẵn sau khi dữ liệu người dùng đã được liên kết (bằng system_boot_reason_prop).

Logic trạng thái khởi động phụ thuộc vào một chế độ cài đặt tuân thủ và có nhiều thông tin hơn bootloader_boot_reason_prop. Khi tài sản đó sử dụng định dạng có thể dự đoán, nó cải thiện độ chính xác của tất cả các lần khởi động lại và cho các tình huống ngừng hoạt động, từ đó tinh chỉnh cũng như mở rộng độ chính xác và ý nghĩa trong tổng số system_boot_reason_prop.

Định dạng lý do khởi động chuẩn

Định dạng lý do khởi động chuẩn của bootloader_boot_reason_prop trong Android 9 sẽ sử dụng cú pháp sau:

<reason>,<subreason>,<detail>…

Quy tắc định dạng:

  • Chữ thường
  • Không có khoảng trống (sử dụng dấu gạch dưới)
  • Tất cả ký tự in được
  • reason, subreason và một hoặc thực thể detail khác.
    • reason bắt buộc đại diện cho mức độ ưu tiên cao nhất lý do khiến thiết bị phải khởi động lại hoặc tắt.
    • subreason (không bắt buộc) đại diện cho nội dung tóm tắt ngắn về lý do tại sao thiết bị phải khởi động lại hoặc tắt (hoặc ai đã khởi động lại hoặc tắt thiết bị).
    • Một hoặc nhiều giá trị detail không bắt buộc. Một detail có thể trỏ đến một hệ thống phụ để hỗ trợ việc xác định hệ thống cụ thể nào dẫn đến subreason. Bạn có thể chỉ định nhiều Giá trị detail thường tuân theo hệ phân cấp tầm quan trọng của chúng. Tuy nhiên, bạn cũng có thể báo cáo nhiều detail giá trị có tầm quan trọng bằng nhau.

Có cân nhắc một giá trị trống cho bootloader_boot_reason_prop bất hợp pháp (vì điều này cho phép các tác nhân khác chèn lý do khởi động sau khi thực tế).

Yêu cầu về lý do

Giá trị được cung cấp cho reason (khoảng đầu tiên, trước khi chấm dứt hoặc dấu phẩy) phải thuộc tập hợp sau, chia thành kernel, mạnh và cùn lý do:

  • bộ nhân:
    • watchdog"
    • "kernel_panic"
  • tập hợp mạnh:
    • "recovery"
    • "bootloader"
  • thanh cùn:
    • "cold". Nói chung, biểu thị việc đặt lại hoàn toàn tất cả các thiết bị, bao gồm cả bộ nhớ.
    • "hard". Thông tin chung cho biết phần cứng có trạng thái riêng đặt lại và ramoops phải giữ lại nội dung cố định.
    • "warm". Thông tin chung cho biết bộ nhớ và thiết bị giữ lại một số trạng thái và ramoops (xem pstore trình điều khiển trong nhân) cửa hàng sao lưu chứa nội dung cố định.
    • "shutdown"
    • "reboot". Thông thường, trạng thái ramoops không xác định và trạng thái phần cứng là không xác định. Đây là giá trị chung Các giá trị cold, hardwarm cung cấp manh mối về mức độ sâu của quá trình đặt lại thiết bị.

Trình tải khởi động phải cung cấp một bộ hạt nhân hoặc một bộ cùn reason, và bạn nên cung cấp subreason nếu có thể xác định. Ví dụ: thao tác nhấn và giữ phím nguồn có thể Bản sao lưu ramoops có lý do khởi động "reboot,longkey".

Không có reason khoảng đầu tiên nào có thể thuộc bất kỳ subreason hoặc detail. Tuy nhiên, do tập hợp nhân hệ điều hành, lý do không thể được tạo bởi không gian của người dùng, "watchdog" có thể được sử dụng lại sau một lý do thiết lập cùn, cùng với thông tin chi tiết về nguồn (ví dụ: "reboot,watchdog,service_manager_unresponsive" hoặc "reboot,software,watchdog").

Lý do khởi động không đòi hỏi chuyên gia có kiến thức nội bộ để giải mã và/hoặc phải dễ đọc được kèm theo báo cáo trực quan. Ví dụ: "shutdown,vbxd" (không tốt), "shutdown,uv" (tốt hơn), "shutdown,undervoltage" (ưu tiên).

Tổ hợp lý do và lý do phụ

Android đặt trước một tập hợp từ reason-subreason các kết hợp không được quá tải trong mức sử dụng bình thường nhưng có thể được sử dụng trên theo từng trường hợp nếu kết hợp phản ánh chính xác các thông tin . Ví dụ về các kiểu kết hợp đặt trước bao gồm:

  • "reboot,userrequested"
  • "shutdown,userrequested"
  • "shutdown,thermal" (từ thermald)
  • "shutdown,battery"
  • "shutdown,battery,thermal" (từ BatteryStatsService)
  • "reboot,adb"
  • "reboot,shell"
  • "reboot,bootloader"
  • "reboot,recovery"

Để biết thêm thông tin, vui lòng tham khảo kBootReasonMap trong system/core/bootstat/bootstat.cpp và git liên kết nhật ký thay đổi trong kho lưu trữ nguồn Android.

Báo cáo lý do khởi động

Mọi lý do khởi động, bất kể là từ trình tải khởi động hay được ghi lại trong quy trình khởi động chuẩn lý do phải được ghi lại trong phần kBootReasonMap của system/core/bootstat/bootstat.cpp. Chiến lược phát hành đĩa đơn kBootReasonMap danh sách là sự kết hợp giữa danh sách tuân thủ và danh sách cũ không tuân thủ. Nhà phát triển trình tải khởi động chỉ nên đăng ký mới lý do tuân thủ ở đây (và không nên đăng ký các lý do không tuân thủ trừ phi sản phẩm đã được vận chuyển nên không thay đổi được).

Bạn nên sử dụng các mục nhập tuân thủ hiện có trong system/core/bootstat/bootstat.cpp và tập thể dục hạn chế trước bằng cách sử dụng chuỗi không tuân thủ. Theo nguyên tắc, công cụ này:

  • OK để báo cáo "kernel_panic" từ trình tải khởi động, vì bootstat có thể kiểm tra ramoops cho kernel_panic signatures để tinh chỉnh lý do phụ vào system_boot_reason_prop chính tắc.
  • Không được để báo cáo một chuỗi không tuân thủ trong kBootReasonMap (chẳng hạn như "panic") trên vì điều này cuối cùng sẽ phá vỡ khả năng tinh chỉnh reason.

Ví dụ: nếu kBootReasonMap chứa "wdog_bark", nhà phát triển trình tải khởi động cần:

  • Thay đổi thành "watchdog,bark" rồi thêm vào danh sách trong kBootReasonMap.
  • Hãy cân nhắc ý nghĩa của "bark" đối với những người chưa quen thuộc với và xác định xem subreason có ý nghĩa hơn có phải là sẵn có.

Xác minh tính tuân thủ lý do khởi động

Hiện tại, Android chưa cung cấp chương trình kiểm thử CTS đang hoạt động có thể chính xác kích hoạt hoặc kiểm tra mọi lý do khởi động mà trình tải khởi động có thể cung cấp; các đối tác vẫn có thể thử chạy kiểm thử thụ động để xác định khả năng tương thích.

Do đó, việc tuân thủ trình tải khởi động đòi hỏi nhà phát triển trình tải khởi động phải tự nguyện tuân thủ tinh thần của các quy tắc và nguyên tắc được mô tả ở trên. Chúng tôi kêu gọi các nhà phát triển đó đóng góp cho AOSP (đặc biệt là cho system/core/bootstat/bootstat.cpp) và sử dụng cơ hội này làm để thảo luận về các vấn đề về lý do khởi động.