Android 9 zawiera te zmiany w specyfikacji przyczyny uruchomienia programu ładującego.
Przyczyny uruchomienia
Program rozruchowy korzysta z unikalnych zasobów sprzętowych i pamięci, aby określić, dlaczego urządzenie zostało ponownie uruchomione. Następnie przekazuje tę informację, dodając androidboot.bootreason=<reason>
do wiersza poleceń jądra Androida podczas uruchamiania. init
następnie tłumaczy ten wiersz poleceń, aby przekazać go do właściwości Androida bootloader_boot_reason_prop
(ro.boot.bootreason
). W przypadku urządzeń z Androidem 12 lub nowszym, które korzystają z jądra w wersji 5.10 lub nowszej, do bootconfig zamiast do wiersza poleceń jądra dodawany jest parametr androidboot.bootreason=<reason>
.
Specyfikacje przyczyny uruchomienia
W poprzednich wersjach Androida określono format przyczyny rozruchu, który nie zawierał spacji, był pisany małymi literami i miał niewiele wymagań (np. w przypadku raportowania kernel_panic
, watchdog
, cold
/warm
/hard
) oraz uwzględniał inne unikalne przyczyny. Ta luźna specyfikacja spowodowała rozpowszechnienie setek niestandardowych (a czasami bezsensownych) ciągów znaków przyczyny rozruchu, co z kolei doprowadziło do sytuacji nie do opanowania. W obecnej wersji Androida ogromna ilość niemal nieczytelnych lub bezsensownych treści zgłaszanych przez program rozruchowy spowodowała problemy z zgodnością w przypadku bootloader_boot_reason_prop
.
W Androidzie 9 zespół Androida uznał, że starszy interfejs bootloader_boot_reason_prop
ma duże znaczenie i nie można go ponownie napisać w czasie działania. Wszelkie ulepszenia specyfikacji przyczyny rozruchu muszą zatem wynikać z interakcji z programistami programu rozruchowego i dostosowywania istniejącego systemu. W tym celu zespół Androida:
- Nawiązywanie kontaktu z programistami programów rozruchowych, aby zachęcić ich do:
- Podaj kanoniczne, rozpoznawalne i łatwe do przeanalizowania przyczyny
bootloader_boot_reason_prop
. - Uczestniczyć w
system/core/bootstat/bootstat.cpp
kBootReasonMap
.
- Podaj kanoniczne, rozpoznawalne i łatwe do przeanalizowania przyczyny
- Dodanie kontrolowanego i przepisywalnego w czasie działania źródła
system_boot_reason_prop
(sys.boot.reason
). Ograniczony zestaw aplikacji systemowych (np.bootstat
iinit
) może przepisywać tę właściwość, ale wszystkie aplikacje mogą mieć przyznane uprawnienia sepolicy do jej odczytywania. - Informowanie użytkowników o przyczynie uruchomienia systemu, aby poczekać, aż dane użytkownika zostaną zamontowane, zanim zaufasz treści w właściwości przyczyny uruchomienia systemu.
system_boot_reason_prop
Dlaczego tak późno? Chociaż bootloader_boot_reason_prop
jest dostępny na wczesnym etapie rozruchu, jest blokowany przez zasady bezpieczeństwa Androida w razie potrzeby, ponieważ zawiera nieprawidłowe, nieczytelne i niekanoniczne informacje.
W większości przypadków dostęp do tych informacji powinni mieć tylko deweloperzy z dogłębną wiedzą o systemie rozruchowym. Ulepszony, analizowalny i kanoniczny interfejs API przyczyny rozruchu z system_boot_reason_prop
można niezawodnie i dokładnie pobrać dopiero po zamontowaniu danych użytkownika.
Więcej szczegółów:
- Przed zamontowaniem danych użytkownika zmienna
system_boot_reason_prop
będzie zawierać wartość z zmiennejbootloader_boot_reason_prop
. - Po zamontowaniu danych użytkownika
system_boot_reason_prop
może zostać zaktualizowany, aby zachować zgodność lub przekazywać dokładniejsze informacje.
Z tego powodu Android 9 wydłuża okres, po którym można oficjalnie uzyskać przyczynę rozruchu, zmieniając go z natychmiastowej dokładności podczas rozruchu (z użyciem bootloader_boot_reason_prop
) na dostępność dopiero po zamontowaniu danych użytkownika (z użyciem system_boot_reason_prop
).
Logika Bootstat zależy od bardziej informacyjnego i zgodnego z przepisami bootloader_boot_reason_prop
. Jeśli ta właściwość używa przewidywalnego formatu, zwiększa to dokładność wszystkich scenariuszy kontrolowanego ponownego uruchamiania i zamykania, co z kolei poprawia i rozszerza dokładność oraz znaczenie system_boot_reason_prop
.
Kanoniczny format przyczyny uruchomienia
Kanoniczny format przyczyny rozruchu w przypadku bootloader_boot_reason_prop
w Androidzie 9 ma następującą składnię:
<reason>,<subreason>,<detail>…
Reguły formatowania:
- Małe litery
- Bez spacji (użyj podkreślenia)
- Wszystkie znaki do wydrukowania
- Rozdzielone przecinkami instancje
reason
,subreason
i co najmniej 1 instancjadetail
.- Wymagany element
reason
, który reprezentuje powód o najwyższym priorytecie, dla którego urządzenie musiało zostać ponownie uruchomione lub wyłączone. - Opcjonalny element
subreason
, który zawiera krótkie podsumowanie przyczyny ponownego uruchomienia lub wyłączenia urządzenia (lub informację o tym, kto ponownie uruchomił lub wyłączył urządzenie). - Co najmniej 1 opcjonalna wartość
detail
. Poledetail
może wskazywać podsystem, co ułatwia określenie, który konkretny system spowodowałsubreason
. Możesz określić wiele wartościdetail
, które powinny być uporządkowane według ważności. Można jednak podawać wiele wartościdetail
o równym znaczeniu.
- Wymagany element
Pusta wartość w przypadku atrybutu bootloader_boot_reason_prop
jest uznawana za nieprawidłową (ponieważ umożliwia innym agentom późniejsze wstawienie przyczyny uruchomienia).
Wymagania dotyczące przyczyny
Wartość podana dla reason
(pierwszy zakres, przed zakończeniem lub przecinkiem) musi należeć do jednego z tych zbiorów podzielonych na przyczyny podstawowe, istotne i ogólne:
- zbiór jądra:
- „
watchdog"
"kernel_panic"
- „
- silny zestaw:
"recovery"
"bootloader"
- blunt set:
"cold"
. Zwykle oznacza pełne zresetowanie wszystkich urządzeń, w tym pamięci."hard"
. Zwykle oznacza, że sprzęt został zresetowany iramoops
powinien zachować trwałą zawartość."warm"
. Zwykle oznacza, że pamięć i urządzenia zachowują pewien stan, aramoops
(patrzpstore
sterownik w jądrze) pamięć podręczna zawiera trwałe treści."shutdown"
"reboot"
. Zwykle oznacza, że stanramoops
jest nieznany, a stan sprzętu jest nieznany. Ta wartość jest ogólna, ponieważ wartościcold
,hard
iwarm
wskazują, jak głębokie jest resetowanie urządzenia.
Programy rozruchowe muszą udostępniać zestaw jądra lub zestaw blunt reason
i zdecydowanie zaleca się, aby udostępniały subreason
, jeśli można to ustalić. Na przykład długie naciśnięcie przycisku zasilania, które może mieć lub nie mieć kopii zapasowejramoops
, będzie miało przyczynę rozruchu"reboot,longkey"
.
Żaden pierwszy zakres reason
nie może być częścią żadnego zakresu subreason
ani detail
. Jednak ponieważ przyczyny ustawienia jądra nie mogą być generowane przez przestrzeń użytkownika, po prostej przyczynie ustawienia można ponownie użyć wartości "watchdog"
wraz ze szczegółami źródła (np. "reboot,watchdog,service_manager_unresponsive"
lub "reboot,software,watchdog"
).
Przyczyny uruchomienia nie powinny wymagać specjalistycznej wiedzy wewnętrznej do rozszyfrowania ani powinny być czytelne dla człowieka w intuicyjnym raporcie. Przykłady:
"shutdown,vbxd"
(źle), "shutdown,uv"
(lepiej),
"shutdown,undervoltage"
(najlepiej).
Kombinacje przyczyna – podprzyczyna
Android rezerwuje zestaw kombinacji reason
–subreason
, których nie należy przeciążać w normalnym użytkowaniu, ale można ich używać w poszczególnych przypadkach, jeśli kombinacja dokładnie odzwierciedla powiązany warunek. Przykłady zarezerwowanych kombinacji:
"reboot,userrequested"
"shutdown,userrequested"
"shutdown,thermal"
(z:thermald
)"shutdown,battery"
"shutdown,battery,thermal"
(zBatteryStatsService
)"reboot,adb"
"reboot,shell"
"reboot,bootloader"
"reboot,recovery"
Więcej informacji znajdziesz w kBootReasonMap
system/core/bootstat/bootstat.cpp
i powiązanej historii zmian w repozytorium kodu źródłowego Androida.
Powody uruchomienia
Wszystkie przyczyny uruchomienia, zarówno z programu rozruchowego, jak i zarejestrowane w kanonicznej przyczynie uruchomienia, muszą być zapisane w sekcji kBootReasonMap
pliku system/core/bootstat/bootstat.cpp
. Lista kBootReasonMap
zawiera zarówno przyczyny zgodne z zasadami, jak i przyczyny starszego typu, które nie są zgodne z zasadami. Deweloperzy programów rozruchowych powinni rejestrować tutaj tylko nowe powody zgodne z zasadami (i nie powinni rejestrować powodów niezgodnych z zasadami, chyba że produkt został już wysłany i nie można go zmienić).
Zdecydowanie zalecamy używanie istniejących, zgodnych wpisów w system/core/bootstat/bootstat.cpp
i zachowanie ostrożności przed użyciem niezgodnego ciągu znaków. Zgodnie z wytycznymi:
- OK, aby zgłosić
"kernel_panic"
z programu rozruchowego, ponieważbootstat
może sprawdzićramoops
pod kątemkernel_panic signatures
, aby doprecyzować przyczyny dodatkowe do kanonicznegosystem_boot_reason_prop
. - Nie, aby zgłosić ciąg znaków niezgodny z zasadami w
kBootReasonMap
(np."panic")
z programu ładującego, ponieważ ostatecznie uniemożliwi to dopracowaniereason
).
Jeśli na przykład kBootReasonMap
zawiera "wdog_bark"
, deweloper programu rozruchowego powinien:
- Zmień na
"watchdog,bark"
i dodaj do listy wkBootReasonMap
. - Zastanów się, co symbol
"bark"
oznacza dla osób, które nie znają tej technologii, i sprawdź, czy dostępny jest bardziej zrozumiały symbolsubreason
.
Sprawdzanie zgodności przyczyny uruchomienia
Obecnie Android nie udostępnia aktywnego testu CTS, który mógłby dokładnie wywoływać lub sprawdzać wszystkie możliwe przyczyny uruchomienia, jakie może podać program rozruchowy. Partnerzy mogą jednak spróbować przeprowadzić test pasywny, aby określić zgodność.
W związku z tym zgodność z programem rozruchowym wymaga od deweloperów programów rozruchowych dobrowolnego przestrzegania ducha zasad i wytycznych opisanych powyżej.
Zachęcamy takich deweloperów do współtworzenia AOSP (zwłaszcza system/core/bootstat/bootstat.cpp
) i wykorzystania tej okazji jako forum do dyskusji o problemach z przyczyną rozruchu.