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

Android 9 bao gồm các thay đổi sau đối với thông số lý do khởi động bộ nạp khởi động.

Lý do khởi động

Bộ tải khởi động sử dụng tài nguyên bộ nhớ và phần cứng 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 thêm androidboot.bootreason=<reason> vào dòng lệnh nhân Android để khởi chạy. init sau đó dịch dòng lệnh này để truyền tới 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ố lý do khởi động

Các bản phát hành trước của Android đã chỉ định định dạng lý do khởi động không sử dụng dấu cách, hoàn toàn là chữ thường, bao gồm một số yêu cầu (chẳng hạn như để báo cáo kernel_panic , watchdog , cold / warm / hard ) và cho phép các lý do riêng khác. Thông số kỹ thuật lỏng lẻo này dẫn đến sự gia tăng của hàng trăm chuỗi lý do khởi động tùy chỉnh (và đôi khi vô nghĩa), từ đó dẫn đến tình huống không thể quản lý được. Kể từ bản phát hành Android hiện tại, động lực tuyệt đối của nội dung gần như không thể phân tích được hoặc vô nghĩa do bộ nạp khởi động cung cấp đã tạo ra các vấn đề tuân thủ cho bootloader_boot_reason_prop .

Với bản phát hành Android 9, nhóm Android nhận thấy rằng bootloader_boot_reason_prop cũ có động lực đáng kể và không thể viết lại trong thời gian chạy. Do đó, bất kỳ cải tiến nào đối với đặc tả lý do khởi động đều phải đến từ sự tương tác với các nhà phát triển bộ nạp khởi động và các chỉnh sửa đối với hệ thống hiện có. Để đạt được mục tiêu đó, nhóm Android là:

  • Tương tác với các nhà phát triển bootloader để khuyến khích họ:
    • Cung cấp các lý do chính tắc, có thể phân tích cú pháp và có thể nhận biết được cho bootloader_boot_reason_prop .
    • Tham gia vào danh sách system/core/bootstat/bootstat.cpp kBootReasonMap .
  • Thêm nguồn được kiểm soát và có thể ghi lại trong thời gian chạy của system_boot_reason_prop ( sys.boot.reason ). Một tập hợp giới hạn các ứ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ả các ứng dụng đều có thể được cấp quyền riêng biệt để đọc nó.
  • Thông báo cho người dùng về lý do khởi động để đợi cho đến khi dữ liệu người dùng được gắn kết trước khi tin cậy nội dung trong thuộc tính lý do khởi động hệ thống system_boot_reason_prop .

Sao trễ vậy? Mặc dù bootloader_boot_reason_prop có sẵn ngay từ đầu khi khởi động nhưng nó bị chính sách bảo mật Android chặn trên cơ sở khi cần vì nó thể hiện 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 về hệ thống khởi động mới cần truy cập thông tin này. API được tinh chỉnh, có thể phân tích cú pháp và chuẩn cho lý do khởi động thông qua system_boot_reason_prop chỉ có thể được chọn một cách đáng tin cậy và chính xác sau khi dữ liệu người dùng đã được gắn kết. Đặc biệt:

  • 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 khoảng thời gian trước khi có thể chính thức lấy lý do khởi động, thay đổi từ chính xác ngay lập tức khi khởi động (với bootloader_boot_reason_prop ) thành chỉ khả dụng sau khi dữ liệu người dùng được gắn kết (với system_boot_reason_prop ).

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

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

Định dạng lý do khởi động chuẩn cho bootloader_boot_reason_prop trong Android 9 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 (dùng gạch dưới)
  • Tất cả các ký tự có thể in được
  • reason được phân tách bằng dấu phẩy , subreason và một hoặc nhiều detail .
    • reason bắt buộc thể hiện lý do có mức ưu tiên cao nhất khiến thiết bị phải khởi động lại hoặc tắt máy.
    • Một lý do phụ tùy chọn thể hiện subreason tóm tắt ngắn gọn về lý do thiết bị phải khởi động lại hoặc tắt máy (hoặc ai đã khởi động lại hoặc tắt thiết bị).
    • Một hoặc nhiều giá trị detail tùy chọn. Một detail có thể trỏ tới một hệ thống con để 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 thứ bậc quan trọng. Tuy nhiên, cũng có thể chấp nhận báo cáo nhiều giá trị detail có tầm quan trọng như nhau.

Giá trị trống cho bootloader_boot_reason_prop được coi là bất hợp pháp (vì điều này cho phép các tác nhân khác đưa ra 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 kết thúc hoặc dấu phẩy) phải thuộc tập hợp sau được chia thành các lý do cốt lõi, mạnh mẽ và thẳng thừng:

  • bộ hạt nhân:
    • " watchdog"
    • "kernel_panic"
  • bộ mạnh:
    • "recovery"
    • "bootloader"
  • bộ cùn:
    • "cold" . Thường biểu thị việc thiết lập lại toàn bộ tất cả các thiết bị, bao gồm cả bộ nhớ.
    • "hard" . Nói chung cho biết phần cứng đã được thiết lập lại trạng thái và ramoops sẽ giữ lại nội dung liên tục.
    • "warm" . Nói chung cho biết bộ nhớ và các thiết bị giữ lại một số trạng thái và kho lưu trữ hỗ trợ ramoops (xem trình điều khiển pstore trong kernel) chứa nội dung liên tục.
    • "shutdown"
    • "reboot" . Nói chung có nghĩa là trạng thái ramoops không xác định và trạng thái phần cứng không xác định. Giá trị này rất đáng chú ý vì các giá trị cold , hardwarm cung cấp manh mối về mức độ thiết lập lại cho thiết bị.

Bộ tải khởi động phải cung cấp một bộ kernel hoặc một reason được đặt rõ ràng và được khuyến khích cung cấp một subreason nếu có thể xác định được lý do đó. Ví dụ: nhấn lâu phím nguồn có thể có hoặc không có bản sao lưu ramoops sẽ có lý do khởi động "reboot,longkey" .

Không có reason đầu tiên nào có thể là một phần của bất kỳ subreason hoặc detail . Tuy nhiên, do không gian người dùng không thể tạo ra các lý do về bộ kernel, "watchdog" có thể được sử dụng lại sau một lý do được đặt rõ ràng, cùng với 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 yêu cầu kiến ​​thức nội bộ của chuyên gia để giải mã và/hoặc con người có thể đọc được bằng báo cáo trực quan. Ví dụ: "shutdown,vbxd" (xấu), "shutdown,uv" (tốt hơn), "shutdown,undervoltage" (ưu tiên).

Sự kết hợp lý do-lý do phụ

Android bảo lưu một tập hợp reason - các kết hợp subreason không được quá tải trong cách sử dụng thông thường nhưng có thể được sử dụng trong từng trường hợp nếu sự kết hợp đó phản ánh chính xác điều kiện liên quan. Ví dụ về các kết hợp dành riêng 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 chi tiết, hãy tham khảo kBootReasonMap trong system/core/bootstat/bootstat.cpp và lịch sử nhật ký thay đổi git liên quan trong kho lưu trữ nguồn Android.

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

Tất cả lý do khởi động, từ bộ nạp khởi động hoặc được ghi trong lý do khởi động chuẩn, phải được ghi lại trong phần kBootReasonMap của system/core/bootstat/bootstat.cpp . Danh sách kBootReasonMap là sự kết hợp của các lý do tuân thủ và không tuân thủ cũ. Các nhà phát triển Bootloader chỉ nên đăng ký những lý do tuân thủ mới tại đây (và không nên đăng ký những lý do không tuân thủ trừ khi sản phẩm đã được xuất xưởng và không thể thay đổi).

Chúng tôi thực sự khuyên 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à thực hiện hạn chế trước khi sử dụng chuỗi không tuân thủ. Như một hướng dẫn, đó là:

  • Được phép báo cáo "kernel_panic" từ bộ nạp khởi động, vì bootstat có thể kiểm tra ramoops để kernel_panic signatures để tinh chỉnh các lý do phụ thành chuẩn system_boot_reason_prop .
  • Không được phép báo cáo chuỗi không tuân thủ trong kBootReasonMap (chẳng hạn như "panic") từ bộ nạp khởi động, 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" thì nhà phát triển bộ nạp khởi động nên:

  • Thay đổi thành "watchdog,bark" và thêm vào danh sách trong kBootReasonMap .
  • Hãy xem xét ý nghĩa của "bark" đối với những người không quen thuộc với công nghệ này và xác định xem có subreason nào có ý nghĩa hơn không.

Xác minh việc tuân thủ lý do khởi động

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

Do đó, việc tuân thủ bootloader yêu cầu các nhà phát triển bootloader 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 như vậy đóng góp cho AOSP (cụ thể là system/core/bootstat/bootstat.cpp ) và sử dụng cơ hội này làm diễn đàn để thảo luận về các vấn đề lý do khởi động.