Android 9 có những 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 riêng biệt để
xác định lý do thiết bị khởi động lại, sau đó truyền đạt thông tin xác định đó bằng cách
thêm androidboot.bootreason=<reason> vào dòng lệnh kernel Android
để khởi chạy. init sau đó 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ị phát hành với Android 12 trở lên, sử dụng phiên bản kernel 5.10 trở lên, androidboot.bootreason=<reason> được thêm vào bootconfig thay vì dòng lệnh kernel.
Quy cách về lý do khởi động
Các bản phát hành trước của Android đã chỉ định một định dạng lý do khởi động không có
dấu cách, tất cả đều là chữ thường, có ít 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 duy nhất khác. Quy cách 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 tuỳ chỉnh (và đôi khi vô nghĩa), từ đó dẫn đến tình trạng không thể quản lý. Kể từ bản phát hành Android hiện tại, động lực lớn 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ể ghi lại trong thời gian chạy. Do đó, mọi cải tiến đối với
quy cách 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 đang:
- Tương tác với nhà phát triển trình tải khởi động để khuyến khích họ:
- Cung cấp các lý do chuẩn, có thể phân tích cú pháp và nhận dạng cho
bootloader_boot_reason_prop. - Tham gia vào danh sách
system/core/bootstat/bootstat.cppkBootReasonMap.
- Cung cấp các lý do chuẩn, có thể phân tích cú pháp và nhận dạng cho
- Thêm một nguồn có thể kiểm soát và ghi lại trong thời gian chạy của
system_boot_reason_prop(sys.boot.reason). Một số ứng dụng hệ thống (chẳng hạn nhưbootstatvà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 để đợi cho đến khi dữ liệu người dùng được gắn kết
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.
Tại sao lại muộn như vậy? Mặc dù bootloader_boot_reason_prop có sẵn từ sớm
trong quá trình khởi động, nhưng thuộc tính này bị chặn bởi chính sách bảo mật của Android theo nhu cầu
vì thuộc tính này đại diện cho 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
mới cần truy cập thông tin này. Bạn chỉ có thể chọn một API tinh chỉnh, có thể phân tích cú pháp và chuẩn 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 kết.
Cụ thể:
- Trước khi dữ liệu người dùng được gắn kết,
system_boot_reason_propsẽ 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_propcó 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 thu thập lý do khởi động, thay đổi từ việc chính xác ngay lập tức trong quá trình khởi động (với bootloader_boot_reason_prop) thành chỉ có sẵn 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 nhiều thông tin hơn và tuân thủ hơn
bootloader_boot_reason_prop. 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 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 và ý 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 dưới)
- Tất cả các ký tự in được
reason,subreasonđược phân tách bằng dấu phẩy và một hoặc nhiều thực thểdetail.reasonbắt buộc đại diện cho 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.subreasonkhông bắt buộc đại diện cho bản 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 người đã khởi động lại hoặc tắt máy ).- Một hoặc nhiều giá trị
detailkhông bắt buộc. Adetailcó thể trỏ đến một hệ thống con để giúp xác định hệ thống cụ thể nào dẫn đếnsubreason. Bạn có thể chỉ định nhiềudetailgiá trị, thường phải tuân theo hệ thống phân cấp mức độ quan trọng. Tuy nhiên, bạn cũng có thể báo cáo nhiềudetailgiá trị có mức độ quan trọng bằng nhau.
Giá trị trống cho bootloader_boot_reason_prop được coi là
không hợp lệ (vì điều này cho phép các tác nhân khác chèn lý do khởi động sau đó).
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 đây được chia thành các lý do kernel, mạnh và chung chung
lý do:
- tập hợp kernel:
- "
watchdog" "kernel_panic"
- "
- tập hợp mạnh:
"recovery""bootloader"
- tập hợp chung chung:
"cold". Thường cho biết quá trình đặt lại hoàn toàn tất cả các thiết bị, bao gồm cả bộ nhớ."hard". Thường cho biết phần cứng đã đặt lại trạng thái vàramoopssẽ giữ lại nội dung liên tục."warm". Thường cho biết bộ nhớ và các thiết bị giữ lại một số trạng thái vàramoops(xempstoretrình điều khiển trong kernel) bộ nhớ sao lưu chứa nội dung liên tục."shutdown""reboot". Thường có nghĩa là trạng tháiramoopskhông xác định và trạng thái phần cứng không xác định. Giá trị này là giá trị chung vì các giá trịcold,hardvàwarmcung cấp thông tin về mức độ đặt lại cho thiết bị.
Trình tải khởi động phải cung cấp một tập hợp kernel hoặc một tập hợp chung chung reason, và
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ể hoặc không có
ramoops bản sao lưu sẽ có lý do khởi động
"reboot,longkey".
Không có reason nào trong khoảng đầu tiên có thể là một phần của bất kỳ subreason hoặc
detail nào. Tuy nhiên, vì các lý do tập hợp kernel không thể được tạo bởi
không gian người dùng, nên "watchdog" có thể được sử dụng lại sau lý do tập hợp chung chung,
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 yêu cầu kiến thức nội bộ chuyên môn để giải mã và/hoặc
phải dễ đọc đối với con người bằng 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 kiểu kết hợp lý do-lý do phụ
Android dành riêng một tập hợp các kiểu kết hợp reason-subreason
không nên bị quá tải trong quá trình sử dụng bình thường nhưng có thể được sử dụng theo từng trường hợp nếu kiểu kết hợp phản ánh chính xác điều kiện liên quan. Sau đây là các ví dụ về kiểu kết hợp dành riêng:
"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ả cá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 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ũ. Nhà phát triển trình tải khởi động chỉ nên đăng ký các lý do tuân thủ mới
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 tuân thủ hiện có trong
system/core/bootstat/bootstat.cpp và hạn chế trước khi
sử dụng chuỗi không tuân thủ. Theo nguyên tắc, đó là:
- OK để báo cáo
"kernel_panic"từ trình tải khởi động, vìbootstatcó thể kiểm traramoopsđể tìmkernel_panic signaturesnhằm tinh chỉnh các lý do phụ thànhsystem_boot_reason_propchuẩn. - Không OK để báo cáo 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ẽ phá vỡ khả năng tinh chỉnhreason.
Ví dụ: nếu kBootReasonMap chứa "wdog_bark",
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. - 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ósubreasonnà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 không cung cấp bài kiểm tra CTS đang hoạt động có thể kích hoạt hoặc kiểm tra chính xác tất cả các lý do khởi động mà trình tải khởi động có thể cung cấp; đối tác vẫn có thể cố gắng chạy bài kiểm tra 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 yêu cầu nhà phát triển trình tải khởi động
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ụ 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.