W systemie Android 9 wprowadzono następujące zmiany w specyfikacji przyczyny rozruchu programu ładującego.
Powody rozruchu
Program ładujący wykorzystuje unikalnie dostępne zasoby sprzętu i pamięci, aby określić, dlaczego urządzenie zostało ponownie uruchomione, a następnie przekazuje tę informację, dodając androidboot.bootreason=<reason>
do wiersza poleceń jądra Androida w celu jego uruchomienia. init
następnie tłumaczy ten wiersz poleceń, aby propagować go do właściwości Androida bootloader_boot_reason_prop
( ro.boot.bootreason
). W przypadku urządzeń uruchamianych z systemem Android 12 lub nowszym i korzystających z jądra w wersji 5.10 lub nowszej, do bootconfig zamiast wiersza poleceń jądra dodawany jest androidboot.bootreason=<reason>
.
Specyfikacje powodu rozruchu
Poprzednie wersje Androida określały format przyczyny rozruchu, który nie zawierał spacji, był pisany małymi literami, zawierał kilka wymagań (takich jak raportowanie kernel_panic
, watchdog
, cold
/ warm
/ hard
) i uwzględniał inne unikalne powody. Ta luźna specyfikacja spowodowała rozprzestrzenienie się setek niestandardowych (i czasami bezsensownych) ciągów znaków powodujących rozruch, co z kolei doprowadziło do sytuacji, której nie można było zarządzać. Począwszy od bieżącej wersji Androida, sam pęd prawie niemożliwych do przeanalizowania lub bezsensownych treści przesyłanych przez program ładujący spowodował problemy ze zgodnością dla bootloader_boot_reason_prop
.
Wraz z wydaniem Androida 9 zespół Androida zdaje sobie sprawę, że starsze bootloader_boot_reason_prop
ma znaczny rozmach i nie można go ponownie zapisać w czasie wykonywania. Wszelkie ulepszenia specyfikacji powodu rozruchu muszą zatem wynikać z interakcji z twórcami programu ładującego i poprawek w istniejącym systemie. W tym celu zespół Androida to:
- Współpraca z twórcami programów ładujących, aby zachęcić ich do:
- Podaj kanoniczne, możliwe do przeanalizowania i rozpoznawalne powody
bootloader_boot_reason_prop
. - Weź udział w liście
system/core/bootstat/bootstat.cpp
kBootReasonMap
.
- Podaj kanoniczne, możliwe do przeanalizowania i rozpoznawalne powody
- Dodanie kontrolowanego źródła z możliwością wielokrotnego zapisu w czasie wykonywania
system_boot_reason_prop
(sys.boot.reason
). Ograniczony zestaw aplikacji systemowych (takich jakbootstat
iinit
) może przepisać tę właściwość, ale wszystkim aplikacjom można przyznać uprawnienia sepolicy do jej odczytu. - Informowanie użytkowników o powodzie rozruchu, aby zaczekali do momentu zamontowania danych użytkownika, zanim zaufają zawartości właściwości powodu rozruchu systemu
system_boot_reason_prop
.
Dlaczego tak późno? Chociaż bootloader_boot_reason_prop
jest dostępny na początku rozruchu, jest blokowany przez zasady bezpieczeństwa Androida w zależności od potrzeb, ponieważ reprezentuje niedokładne, niemożliwe do przeanalizowania i niekanoniczne informacje. W większości sytuacji dostęp do tych informacji powinni mieć jedynie programiści posiadający głęboką wiedzę na temat systemu rozruchowego. Udoskonalony, analizowalny i kanoniczny interfejs API do celów rozruchu za pośrednictwem system_boot_reason_prop
można niezawodnie i dokładnie pobrać dopiero po zamontowaniu danych użytkownika. Konkretnie:
- Zanim dane użytkownika zostaną zamontowane,
system_boot_reason_prop
będzie zawierać wartość zbootloader_boot_reason_prop
. - Po zamontowaniu danych użytkownika
system_boot_reason_prop
może zostać zaktualizowany w celu zapewnienia zgodności lub raportowania dokładniejszych informacji.
Z tego powodu Android 9 wydłuża okres czasu, po którym można oficjalnie ustalić przyczynę rozruchu, zmieniając go z natychmiastowego dokładnego rozruchu (z bootloader_boot_reason_prop
) na dostępny dopiero po zamontowaniu danych użytkownika (z system_boot_reason_prop
).
Logika Bootstat zależy od bardziej informacyjnego i zgodnego bootloader_boot_reason_prop
. Gdy ta właściwość używa przewidywalnego formatu, poprawia dokładność wszystkich kontrolowanych scenariuszy ponownego uruchamiania i zamykania, co z kolei udoskonala i rozszerza dokładność i znaczenie system_boot_reason_prop
.
Kanoniczny format przyczyny rozruchu
Kanoniczny format przyczyny rozruchu dla bootloader_boot_reason_prop
w systemie Android 9 wykorzystuje następującą składnię:
<reason>,<subreason>,<detail>…
Zasady formatowania:
- Małe litery
- Bez spacji (użyj podkreślenia)
- Wszystkie znaki do wydrukowania
- Oddzielona przecinkami
reason
,subreason
i co najmniej jedendetail
.- Wymagany
reason
, który reprezentuje powód o najwyższym priorytecie, dla którego urządzenie musiało zostać ponownie uruchomione lub wyłączone. - Opcjonalny
subreason
reprezentujący krótkie podsumowanie tego, dlaczego urządzenie musiało zostać ponownie uruchomione lub wyłączone (albo kto ponownie uruchomił lub zamknął urządzenie). - Co najmniej jedna opcjonalna wartość
detail
.detail
może wskazywać na podsystem, co pomoże w ustaleniu, który konkretny system spowodował danąsubreason
. Można określić wiele wartościdetail
, które zazwyczaj powinny być zgodne z hierarchią ważności. Jednakże dopuszczalne jest również zgłaszanie wielu wartościdetail
o jednakowym znaczeniu.
- Wymagany
Pusta wartość bootloader_boot_reason_prop
jest uważana za nielegalną (ponieważ pozwala to innym agentom na podanie przyczyny rozruchu po fakcie).
Powód wymagań
Wartość podana jako reason
(pierwszy zakres, przed zakończeniem lub przecinkiem) musi należeć do następującego zestawu podzielonego na przyczyny jądra, mocne i tępe:
- zestaw jądra:
- „
watchdog"
-
"kernel_panic"
- „
- mocny zestaw:
-
"recovery"
-
"bootloader"
-
- tępy zestaw:
-
"cold"
. Ogólnie oznacza pełny reset wszystkich urządzeń, łącznie z pamięcią. -
"hard"
. Ogólnie wskazuje, że stan sprzętu został zresetowany, aramoops
powinny zachować trwałą zawartość. -
"warm"
. Ogólnie wskazuje, że pamięć i urządzenia zachowują pewien stan, a magazyn zapasowyramoops
(patrz sterownikpstore
w jądrze) zawiera trwałą zawartość. -
"shutdown"
-
"reboot"
. Ogólnie oznacza, że stanramoops
jest nieznany i stan sprzętu jest nieznany. Ta wartość jest chwytliwa, ponieważ wartościcold
,hard
iwarm
dostarczają wskazówek co do głębokości resetowania urządzenia.
-
Programy ładujące muszą podać zestaw jądra lub bezpośredni reason
i zdecydowanie zaleca się podanie subreason
, jeśli można go ustalić. Na przykład długie naciśnięcie klawisza zasilania, które może mieć kopię zapasową ramoops
lub nie, spowoduje uruchomienie jako "reboot,longkey"
.
Żaden reason
pierwszego zakresu nie może być częścią żadnego powodu subreason
ani detail
. Jednakże, ponieważ przestrzeń użytkownika nie może określić przyczyn ustawienia jądra, "watchdog"
może zostać ponownie użyty po tępym ustawionym powodzie, wraz ze szczegółami źródła (np. "reboot,watchdog,service_manager_unresponsive"
lub "reboot,software,watchdog"
).
Przyczyny rozruchu nie powinny wymagać wewnętrznej wiedzy eksperckiej do rozszyfrowania i/lub powinny być czytelne dla człowieka za pomocą intuicyjnego raportu. Przykłady: "shutdown,vbxd"
(złe), "shutdown,uv"
(lepsze), "shutdown,undervoltage"
(preferowane).
Kombinacje przyczyny i podpowodu
Android zastrzega sobie zestaw kombinacji reason
i subreason
, które nie powinny być przeciążane podczas normalnego użytkowania, ale można ich używać w indywidualnych przypadkach, jeśli kombinacja dokładnie odzwierciedla powiązany stan. Przykłady zarezerwowanych kombinacji obejmują:
-
"reboot,userrequested"
-
"shutdown,userrequested"
-
"shutdown,thermal"
(zthermald
) -
"shutdown,battery"
-
"shutdown,battery,thermal"
(zBatteryStatsService
) -
"reboot,adb"
-
"reboot,shell"
-
"reboot,bootloader"
-
"reboot,recovery"
Aby uzyskać więcej informacji, zobacz kBootReasonMap
w system/core/bootstat/bootstat.cpp
i powiązaną historię dziennika zmian git w repozytorium źródłowym Androida.
Zgłaszanie przyczyn rozruchu
Wszystkie przyczyny rozruchu, czy to z programu ładującego, czy zapisane w kanonicznym powodzie rozruchu, muszą zostać zapisane w sekcji kBootReasonMap
pliku system/core/bootstat/bootstat.cpp
. Lista kBootReasonMap
jest mieszanką powodów zgodnych i starszych, niezgodnych. Programiści programu ładującego powinni rejestrować tutaj tylko nowe przyczyny zgodne (i nie powinni rejestrować powodów niezgodnych, chyba że produkt został już wysłany i nie można go zmienić).
Zdecydowanie zalecamy użycie istniejących, zgodnych wpisów w system/core/bootstat/bootstat.cpp
i zachowanie powściągliwości przed użyciem niezgodnego ciągu. Jako wytyczną jest to:
- OK , aby zgłosić
"kernel_panic"
z bootloadera, ponieważbootstat
może być w stanie sprawdzićramoops
pod kątemkernel_panic signatures
, aby udoskonalić przyczyny podrzędne w kanonicznysystem_boot_reason_prop
. - Niewłaściwe jest zgłaszanie niezgodnego ciągu znaków w
kBootReasonMap
(takiego jak"panic")
z programu ładującego, ponieważ ostatecznie uniemożliwi to doprecyzowaniereason
.
Na przykład, jeśli kBootReasonMap
zawiera "wdog_bark"
, programista bootloadera powinien:
- Zmień na
"watchdog,bark"
i dodaj do listy wkBootReasonMap
. - Zastanów się, co
"bark"
oznacza dla osób niezaznajomionych z technologią i ustal, czy dostępny jest bardziej znaczącysubreason
.
Sprawdzanie zgodności przyczyny rozruchu
W tej chwili system Android nie zapewnia aktywnego testu CTS, który mógłby dokładnie uruchomić lub sprawdzić wszystkie możliwe przyczyny rozruchu, jakie może zapewnić program ładujący; partnerzy mogą nadal próbować przeprowadzić test pasywny w celu ustalenia zgodności.
W rezultacie zgodność programu ładującego wymaga od jego twórców dobrowolnego przestrzegania zasad i wytycznych opisanych powyżej. Wzywamy takich programistów do wnoszenia wkładu w AOSP (w szczególności do system/core/bootstat/bootstat.cpp
) i wykorzystywania tej okazji jako forum do dyskusji na temat przyczyn uruchamiania.