Android 9 có các thay đổi sau đây đối với quy cách 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 bộ nhớ và phần cứng có sẵn riêng biệt để xác định lý do thiết bị khởi động lại, sau đó thông báo quyết định đó bằng cách thêm androidboot.bootreason=<reason>
vào dòng lệnh hạt nhân Android để khởi chạy. Sau đó, init
sẽ dịch dòng lệnh này để truyền đến thuộc tính Android bootloader_boot_reason_prop
(ro.boot.bootreason
). Đối với các thiết bị khởi chạy bằng Android 12 trở lên, sử dụng hạt nhân phiên bản 5.10 trở lên, androidboot.bootreason=<reason>
sẽ được thêm vào bootconfig thay vì dòng lệnh hạt nhân.
Thông số kỹ thuật về lý do khởi động
Các bản phát hành trước đây của Android đã chỉ định định dạng lý do khởi động không sử dụng dấu cách, tất cả đều là chữ thường, kèm theo một số yêu cầu (chẳng hạn như đối với báo cáo kernel_panic
, watchdog
, cold
/warm
/hard
) và định dạng cho phép vì những lý do riêng biệt khác. Thông số kỹ thuật lỏng lẻo này đã dẫn đến việc hàng trăm chuỗi lý do khởi động tuỳ chỉnh (và đôi khi vô nghĩa) xuất hiện, từ đó dẫn đến một tình huống không thể quản lý. Kể từ bản phát hành Android hiện tại, động lực thuần tuý 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 đã tạo ra các vấn đề về việc tuân thủ đối với 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 đó, mọi điểm cải tiến đối với thông số kỹ thuật về lý do khởi động phải đến từ các hoạt động tương tác với nhà phát triển trình tải khởi động và các điều chỉnh đối với hệ thống hiện có. Để đạt được mục tiêu đó, nhóm Android sẽ:
- 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ọ:
- Cung cấp lý do chính thống, có thể phân tích cú pháp và dễ nhận biết cho
bootloader_boot_reason_prop
. - Tham gia danh sách
system/core/bootstat/bootstat.cpp
kBootReasonMap
.
- Cung cấp lý do chính thống, có thể phân tích cú pháp và dễ nhận biết cho
- Thêm một 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 nhóm ứng dụng hệ thống có giới hạn (chẳng hạn nhưbootstat
vàinit
) có thể ghi 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 thuộc tính này. - 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 rồi mới tin tưởng nội dung trong thuộc tính lý do khởi động hệ thống
system_boot_reason_prop
.
Tại sao lại trễ vậy? Mặc dù bootloader_boot_reason_prop
có sẵn trong quá trình khởi động, nhưng chính sách bảo mật của Android sẽ chặn bootloader_boot_reason_prop
khi cần vì bootloader_boot_reason_prop
đại diện cho thông tin không chính xác, không 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 chuyên sâu về hệ thống khởi động mới cần truy cập vào thông tin này. Bạn chỉ có thể chọn một API tinh tế, có thể phân tích cú pháp và chuẩn hoá cho lý do khởi động bằng system_boot_reason_prop
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.
Cụ thể:
- Trước khi userdata được gắn,
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ủ chính sách 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ể thu thập chính thức lý do khởi động, thay đổi từ việc ngay lập tức chính xác trong quá trình khởi động (với bootloader_boot_reason_prop
) thành chỉ có sẵn sau khi userdata được gắn (với system_boot_reason_prop
).
Logic Bootstat phụ thuộc vào một bootloader_boot_reason_prop
tuân thủ và cung cấp nhiều thông tin hơn. Khi thuộc tính đó sử dụng định dạng có thể dự đoán, thuộc tính đó sẽ cải thiện độ chính xác của tất cả các trường hợp khởi động lại và tắt đượ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 (sử dụng dấu gạch chân)
- Tất cả ký tự in được
reason
,subreason
và một hoặc nhiều thực thểdetail
được phân tách bằng dấu phẩy.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.subreason
không bắt buộc, trình bày tóm tắt ngắn gọn lý do thiết bị phải khởi động lại hoặc tắt (hoặc người đã 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.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 đếnsubreason
. Bạn có thể chỉ định nhiều giá trịdetail
, thường tuân theo hệ thống phân cấp theo mức độ quan trọng. Tuy nhiên, bạn cũng có thể 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 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
(span đầu tiên, trước dấu chấm hoặc dấu phẩy) phải thuộc tập hợp sau đây, được chia thành các lý do chính, mạnh và thẳng thắn:
- bộ nhân hệ điều hành:
- "
watchdog"
"kernel_panic"
- "
- tập hợp mạnh:
"recovery"
"bootloader"
- bộ blunt:
"cold"
. Nói chung, biểu tượng này cho biết tất cả thiết bị đã được đặt lại hoàn toàn, bao gồm cả bộ nhớ."hard"
. Thường cho biết phần cứng đã đặt lại trạng thái vàramoops
sẽ giữ lại nội dung ổn định."warm"
. Thường thì biểu thị bộ nhớ và các thiết bị giữ lại một số trạng thái và kho lưu trữ sao lưuramoops
(xem trình điều khiểnpstore
trong nhân) chứa nội dung cố định."shutdown"
"reboot"
. Nói chung, có nghĩa là không xác định được trạng thái củaramoops
và không xác định được trạng thái phần cứng. Giá trị này là một giá trị tổng hợp vì các giá trịcold
,hard
vàwarm
cung cấp các gợi ý về chiều 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 nhóm hạt nhân hoặc một nhóm cùn reason
, và bạn nên cung cấp một subreason
nếu có thể xác định được. Ví dụ: thao tác nhấn và giữ 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 là "reboot,longkey"
.
Không có reason
span đầu tiên nào có thể là một phần của subreason
hoặc detail
. Tuy nhiên, vì không gian người dùng không thể tạo lý do đặt hạt nhân, nên "watchdog"
có thể được sử dụng lại sau khi đặt lý do thô, 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 kiến thức nội bộ của chuyên gia để giải mã và/hoặc phải dễ đọc đối với con người thông qua một 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).
Các tổ hợp lý do-lý do phụ
Android dành riêng một tập hợp các tổ hợp reason
-subreason
không được nạp chồng trong trường hợp sử dụng thông thường nhưng có thể được sử dụng theo từng trường hợp nếu tổ hợp phản ánh chính xác điều kiện liên quan. 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 chi tiết, hãy tham khảo kBootReasonMap
trong system/core/bootstat/bootstat.cpp
và 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ừ trình tải khởi động hoặc được ghi lại trong lý do khởi động chính tắc, phải được ghi lại trong phần kBootReasonMap
của system/core/bootstat/bootstat.cpp
. Danh sách kBootReasonMap
bao gồm cả lý do tuân thủ và lý do không tuân thủ cũ. Nhà phát triển trình tải khởi động chỉ nên đăng ký các lý do mới tuân thủ tại đâ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 và không thể thay đổi).
Bạn nên sử dụng các mục hiện có, tuân thủ trong system/core/bootstat/bootstat.cpp
và hạn 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 traramoops
chokernel_panic signatures
để tinh chỉnh các lý do phụ thànhsystem_boot_reason_prop
chuẩn. - Không được báo cáo một chuỗi không tuân thủ trong
kBootReasonMap
(chẳng hạn như"panic")
từ trình tải khởi động, vì điều này cuối cùng sẽ làm hỏng khả năng tinh chỉnhreason
.
Ví dụ: nếu kBootReasonMap
chứa "wdog_bark"
, thì nhà phát triển trình tải khởi động nên:
- Thay đổi thành
"watchdog,bark"
và thêm vào danh sách trongkBootReasonMap
. - Hãy cân nhắc ý 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
Hiện tại, Android chưa cung cấp chương trình kiểm thử CTS đang hoạt động có thể kích hoạt hoặc kiểm tra chính xác mọi lý do khởi động mà trình tải khởi động có thể đưa ra. 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 đó, để tuân thủ quy định về trình tải khởi động, 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 khuyến khích những nhà phát triển như vậy đóng góp cho AOSP (cụ thể là cho 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 đề liên quan đến lý do khởi động.