Android 9 zawiera te zmiany specyfikacji powodu uruchamiania bootloadera:
Powody uruchamiania
Program rozruchowy wykorzystuje dostępne wyłącznie zasoby sprzętowe i pamięci, aby określić, dlaczego urządzenie zostało ponownie uruchomione, a następnie przesyła tę informację, dodając androidboot.bootreason=<reason>
do wiersza poleceń jądra Androida. init
przekształca to polecenie w celu propagowania do właściwości Androida bootloader_boot_reason_prop
(ro.boot.bootreason
).init
bootloader_boot_reason_prop
ro.boot.bootreason
androidboot.bootreason=<reason>
Specyfikacja przyczyny uruchamiania
W poprzednich wersjach Androida format powodu rozruchu nie zawierał spacji, był w pełni pisany małymi literami, uwzględniał kilka wymagań (np. dotyczących raportowania kernel_panic
, watchdog
, cold
/warm
/hard
) i umożliwiał inne unikalne powody. Ta luźna specyfikacja spowodowała rozpowszechnienie setek niestandardowych (a czasem bezsensownych) ciągów znaków powodu rozruchu, co z kolei doprowadziło do niekontrolowanej sytuacji. W ramach obecnej wersji Androida ilość treści, które są prawie nie do zinterpretowania lub bez znaczenia, przesłanych przez program rozruchowy, spowodowała problemy z zgodnością w przypadku bootloader_boot_reason_prop
.
W Androidzie 9 zespół Androida zdał sobie sprawę, że starsza wersja bootloader_boot_reason_prop
ma znaczną dynamikę i nie można jej ponownie napisać w czasie wykonywania. Wszelkie ulepszenia specyfikacji przyczyny rozruchu muszą więc pochodzić od programistów bootloadera i polegać na interakcji z dotychczasowym systemem. W związku z tym zespół Androida:
- Zaangażowanie deweloperów programów rozruchowych w zachęcanie ich do:
- Podaj kanoniczne, możliwe do zanalizowania i rozpoznawania powody, dla których chcesz to zrobić:
bootloader_boot_reason_prop
. - Znajdź się na liście
system/core/bootstat/bootstat.cpp
kBootReasonMap
.
- Podaj kanoniczne, możliwe do zanalizowania i rozpoznawania powody, dla których chcesz to zrobić:
- Dodanie kontrolowanego źródła danych
system_boot_reason_prop
(sys.boot.reason
), które można zapisywać na etapie wykonywania. Ten obiekt może być zastępowany przez ograniczony zestaw aplikacji systemowych (takich jakbootstat
iinit
), ale wszystkie aplikacje mogą mieć uprawnienia do jego odczytu. - Informowanie użytkowników o powodzie rozruchu i proszeniu ich o poczekanie, aż dane użytkownika zostaną zamontowane, zanim zaufają treści w właściwości powodu rozruchu systemu.
system_boot_reason_prop
Dlaczego tak późno? Chociaż interfejs bootloader_boot_reason_prop
jest dostępny na wczesnym etapie uruchamiania, w razie potrzeby jest on blokowany przez zasadę zabezpieczeń Androida, ponieważ przedstawia niedokładne, niemożliwe do przeanalizowania i niekanoniczne informacje.
W większości przypadków dostęp do tych informacji powinni uzyskać tylko deweloperzy, którzy mają dogłębną wiedzę o systemie rozruchowym. Ulepszony, możliwy do zanalizowania i kanoniczny interfejs API dla powodu rozruchu z system_boot_reason_prop
może być wiarygodnie i precyzyjnie pobierany tylko po zamontowaniu danych użytkownika.
Więcej szczegółów:
- Zanim userdata zostanie zamontowane,
system_boot_reason_prop
będzie zawierać wartość zbootloader_boot_reason_prop
. - Po podłączeniu danych użytkowników obiekt
system_boot_reason_prop
może zostać zaktualizowany, aby zapewnić zgodność lub podawać dokładniejsze informacje.
Z tego powodu Android 9 wydłuża okres, w którym można oficjalnie uzyskać przyczynę rozruchu, zmieniając ją z natychmiastowej dokładności podczas rozruchu (z bootloader_boot_reason_prop
) na dostępność dopiero po zamontowaniu danych użytkownika (z system_boot_reason_prop
).
Logika bootstat zależy od bardziej przydatnych i zgodny z wymaganiami
bootloader_boot_reason_prop
. Jeśli usługa korzysta z przewidywalnego formatu, zwiększa się dokładność wszystkich kontrolowanych scenariuszy ponownego uruchamiania i wyłączania, co z kolei pozwala zwiększyć dokładność i znaczenie system_boot_reason_prop
.
Kanoniczny format powodu uruchamiania
Kanoniczny format powodu uruchamiania dla bootloader_boot_reason_prop
w Androidzie 9 używa tej składni:
<reason>,<subreason>,<detail>…
Reguły formatowania:
- Małe litery
- Bez pustych pól (użyj podkreślenia)
- wszystkie znaki drukowalne.
reason
,subreason
i co najmniej 1 występdetail
rozdzielone przecinkami.- Wymagane
reason
, które reprezentuje najwyższy priorytet powód, dla którego urządzenie musiało się ponownie uruchomić lub wyłączyć. - Opcjonalny element
subreason
, który zawiera krótkie podsumowanie tego, dlaczego urządzenie musiało zostać ponownie uruchomione lub wyłączone (lub kto je uruchomił lub wyłączył). - Co najmniej 1 opcjonalna wartość
detail
.detail
może wskazywać podsystem, aby ułatwić określenie, który konkretny system spowodowałsubreason
. Możesz określić wiele wartościdetail
, które powinny być uporządkowane według hierarchii ważności. Możesz jednak zgłosić kilka wartościdetail
o równym znaczeniu.
- Wymagane
Pusta wartość parametru bootloader_boot_reason_prop
jest uważana za nielegalną (ponieważ pozwala innym agentom na wstrzyknięcie przyczyny uruchomienia po fakcie).
Wymagania dotyczące uzasadnienia
Wartość podana w polu reason
(pierwszy zakres, przed zakończeniem lub przecinkiem) musi należeć do tego zestawu z podziałem na jądro, silne i twarde przyczyny:
- zestaw jądra:
- „
watchdog"
"kernel_panic"
- „
- silny zestaw:
"recovery"
"bootloader"
- zestaw do palenia:
"cold"
. Ogólnie oznacza pełny reset wszystkich urządzeń, w tym pamięci."hard"
. Ogólnie oznacza to, że sprzęt został zresetowany iramoops
powinien zachować trwałe treści."warm"
. Ogólnie oznacza to, że pamięć i urządzenia zachowują pewien stan, a pamięć podręcznaramoops
(patrz:pstore
driver w rdzeniu) zawiera treści trwałe."shutdown"
"reboot"
. Oznacza to, że stanramoops
jest nieznany, a stan sprzętu jest nieznany. Jest to uniwersalna wartość, ponieważ wartościcold
,hard
iwarm
wskazują, do jakiej głębokości resetowania urządzenia należą dane.
Programy rozruchowe muszą udostępniać zestaw jądra lub tępy (reason
). Zdecydowanie zalecamy też dodanie subreason
, jeśli można go określić. Na przykład przytrzymanie przycisku zasilania z ramoops
kopią zapasową lub bez niej będzie miało powód rozruchu"reboot,longkey"
.
Żaden element pierwszego zakresu reason
nie może być częścią żadnego elementu subreason
ani detail
. Jednak ponieważ przyczyny zestawów jądra nie mogą być generowane przez przestrzeń użytkownika, "watchdog"
może być używany ponownie po użyciu prostej przyczyny zestawu wraz ze szczegółami źródła (na przykład "reboot,watchdog,service_manager_unresponsive"
lub "reboot,software,watchdog"
).
Powody rozrywania nie powinny wymagać znajomości wewnętrznych informacji, aby je rozszyfrować, lub powinny być zrozumiałe dla człowieka w intuicyjnym raporcie. Przykłady: "shutdown,vbxd"
(złe), "shutdown,uv"
(lepsze), "shutdown,undervoltage"
(preferowane).
Kombinacje przyczyny i podprzyczyny
Android rezerwuje zestaw kombinacji reason
-subreason
, które nie powinny być przeciążone podczas normalnego użytkowania, ale mogą być używane w każdym przypadku, jeśli kombinacja dokładnie odzwierciedla powiązane warunki. Przykłady zarezerwowanych kombinacji:
"reboot,userrequested"
"shutdown,userrequested"
"shutdown,thermal"
(z:thermald
)"shutdown,battery"
"shutdown,battery,thermal"
(z:BatteryStatsService
)"reboot,adb"
"reboot,shell"
"reboot,bootloader"
"reboot,recovery"
Więcej informacji znajdziesz w kBootReasonMap
w system/core/bootstat/bootstat.cpp
oraz w powiązanej historii zmian w gałęzi git w repozytorium kodu źródłowego Androida.
Zgłaszanie przyczyny uruchomienia
Wszystkie przyczyny uruchamiania (pochodzące z programu rozruchowego lub zarejestrowane w kanonicznej przyczynie uruchamiania) muszą być zarejestrowane w sekcji kBootReasonMap
systemu system/core/bootstat/bootstat.cpp
. Lista kBootReasonMap
zawiera zarówno zgodne, jak i starsze przyczyny niezgodności. Deweloperzy programów ładowania bootloadera powinni rejestrować tylko nowe
zgodne powody (nie powinni rejestrować niezgodnych powodów, chyba że
produkt został już wysłany i nie można go zmienić).
Zdecydowanie zalecamy korzystanie z dotychczasowych zgodnych wpisów w system/core/bootstat/bootstat.cpp
i zachowanie ostrożności przed użyciem niespełniającego wymogów ciągu znaków. Oto kilka wskazówek:
- OK, aby zgłosić
"kernel_panic"
z bootloadera, ponieważbootstat
może sprawdzićramoops
pod kątemkernel_panic signatures
, aby doprecyzować przyczyny podrzędne w kanonicznymsystem_boot_reason_prop
. - Nie jest to dopuszczalne, aby zgłosić niezgodny ciąg tekstowy w
kBootReasonMap
(np."panic")
z bootloadera), ponieważ spowoduje to utratę możliwości doprecyzowaniareason
.
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 oznacza
"bark"
dla osób, które nie znają tej technologii, i sprawdź, czy dostępna jest bardziej odpowiedniasubreason
.
Sprawdzanie zgodności z przyczyną uruchomienia
Obecnie Android nie udostępnia aktywnego testu CTS, który pozwoliłby dokładnie aktywować lub sprawdzić wszystkie możliwe przyczyny rozruchu, jakie może zapewnić program rozruchowy. Partnerzy nadal mogą próbować przeprowadzić pasywny test, aby określić zgodność.
W związku z tym zgodność programu rozruchowego wymaga od jego programistów dobrowolnego przestrzegania ducha reguł i wytycznych opisanych powyżej.
Zachęcamy takich deweloperów do tworzenia w ramach AOSP (szczególnie w ramach system/core/bootstat/bootstat.cpp
) i wykorzystywania tej okazji jako forum do dyskusji na temat przyczyn uruchamiania.