Android 9 zawiera te zmiany specyfikacji powodu uruchamiania bootloadera:
Powody uruchamiania
Bootloader używa unikalnych zasobów sprzętowych i pamięciowych, aby określić, dlaczego urządzenie zostało ponownie uruchomione, a potem przekazuje tę informację, dodając androidboot.bootreason=<reason>
do wiersza poleceń jądra Androida. init
przekształca następnie tę linię poleceń w celu propagowania jej do właściwości Androida bootloader_boot_reason_prop
(ro.boot.bootreason
). W przypadku urządzeń uruchamianych z Androidem 12 lub nowszym, które używają jądra w wersji 5.10 lub nowszej, do bootconfiga zamiast linii poleceń jądra dodawany jest parametr androidboot.bootreason=<reason>
.
Specyfikacje przyczyny uruchomienia
W poprzednich wersjach Androida format powodu rozruchu nie zawierał spacji, był w pełni w małej literze, miał niewiele 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 zgodnoscią z zasadami w przypadku bootloader_boot_reason_prop
.
W ramach Androida 9 zespół Androida zdaje 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:
- Współpraca z deweloperami programów rozruchowych w celu zachęcenia ich do:
- Podaj kanoniczne, możliwe do zanalizowania i rozpoznawania przyczyny, które uzasadniają:
bootloader_boot_reason_prop
. - uczestniczyć w programie
system/core/bootstat/bootstat.cpp
kBootReasonMap
.
- Podaj kanoniczne, możliwe do zanalizowania i rozpoznawania przyczyny, które uzasadniają:
- 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ż bootloader_boot_reason_prop
jest dostępny na początku rozruchu, jest blokowany przez zasady zabezpieczeń Androida w miarę potrzeby, ponieważ zawiera nieprawidłowe, nierozpoznawalne i niekanoniczne informacje.
W większości przypadków dostęp do tych informacji powinni mieć tylko deweloperzy, którzy mają dogłębną wiedzę na temat systemu uruchamiania. 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 zamontowaniu userdata
system_boot_reason_prop
może zostać zaktualizowany, aby był zgodny z wymaganiami lub aby przekazywał 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ępną dopiero po zamontowaniu danych użytkownika (z system_boot_reason_prop
).
Logika bootstat zależy od bardziej przydatnych i zgodny z przepisami
bootloader_boot_reason_prop
. Jeśli usługa korzysta z przewidywalnego formatu, zwiększa się dokładność wszystkich scenariuszy kontrolowanego ponownego uruchamiania i wyłączania, co z kolei pozwala zwiększyć dokładność i znaczenie system_boot_reason_prop
.
Kanoniczny format przyczyny 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
- Brak pustych miejsc (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. Dopuszczalne jest też raportowanie wielu wartościdetail
o równym znaczeniu.
- Wymagane
Pustą wartość atrybutu bootloader_boot_reason_prop
uznaje się za nielegalną (ponieważ pozwala innym procesom wstrzyknąć przyczynę rozruchu w dowolnym momencie).
Wymagania dotyczące uzasadnienia
Wartość podana dla reason
(pierwszy element zakresu, przed przecinkiem) musi należeć do jednego z tych zbiorów podzielonych na przyczyny podstawowe, silne i ostre:
- kernel set:
- „
watchdog"
"kernel_panic"
- „
- strong set:
"recovery"
"bootloader"
- zestaw do palenia:
"cold"
. Zazwyczaj 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 sterownikpstore
w rdzeniu) zawiera trwałe dane."shutdown"
"reboot"
. Oznacza to, że stanramoops
jest nieznany, a stan sprzętu jest nieznany. Ta wartość jest zbiorcza, ponieważ wartościcold
,hard
iwarm
wskazują na głębokość resetu urządzenia.
Bootloadery muszą zawierać zestaw jądra lub zestaw Blunt reason
. Zalecamy również podanie subreason
, jeśli jest to możliwe. 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 uruchamiania nie powinny wymagać znajomości wewnętrznych informacji, aby je zrozumieć, lub powinny być czytelne dla człowieka w ramach intuicyjnego raportu. Przykłady:
"shutdown,vbxd"
(nieprawidłowe), "shutdown,uv"
(lepsze),
"shutdown,undervoltage"
(preferowane).
Kombinacje przyczyny i podprzyczyny
Android rezerwuje zestaw kombinacji reason
-subreason
, które nie powinny być przeciążone w ramach 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 przyczyn uruchamiania
Wszystkie przyczyny rozruchu, zarówno z bootloadera, jak i zapisane w kanonicznych przyczynach rozruchu, muszą być zarejestrowane w sekcji kBootReasonMap
w pliku system/core/bootstat/bootstat.cpp
. Lista kBootReasonMap
zawiera zarówno zgodne, jak i starsze przyczyny niezgodności. Deweloperzy programów ładujących 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ć niespełniający wymogów ciąg znaków 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 mógłby dokładnie wywołać lub sprawdzić wszystkie możliwe powody uruchamiania przez bootloader. Partnerzy mogą jednak spróbować przeprowadzić test pasywny, aby określić zgodność.
Dlatego zgodność z tymi zasadami wymaga od deweloperów bootloaderów dobrowolnego przestrzegania zasad 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 korzystanie z tej okazji jako forum do dyskusji na temat przyczyn uruchamiania.