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 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 zgodnoscią z zasadami 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 programu rozruchowego 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 powody, dla których chcesz to zrobić:
bootloader_boot_reason_prop
. - Dołącz do listy
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 zachęcanie ich do oczekiwania na zamontowanie danych użytkownika, 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, nierozkładalne 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ć niezawodnie i dokładnie 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ępność 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 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
- Brak pustych miejsc (użyj podkreślenia)
- wszystkie znaki drukowalne.
reason
,subreason
i co najmniej 1 występdetail
rozdzielone przecinkami.- Wymagane pole
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 podać 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 pole
Pustą wartość atrybutu bootloader_boot_reason_prop
uważa się za nielegalną (ponieważ pozwala to innym agentom na wstrzyknięcie przyczyny rozruchu po fakcie).
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 opcją ramoops
kopii zapasowej lub bez niej może mieć 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ć 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 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 przyczyn uruchamiania
Wszystkie przyczyny rozruchu, zarówno z bootloadera, jak i zapisane w kanonicznych przyczynach rozruchu, muszą być zarejestrowane w sekcji kBootReasonMap
w system/core/bootstat/bootstat.cpp
. kBootReasonMap
to lista zawierająca zarówno zgodne, jak i starsze przyczyny niezgodności. Deweloperzy programów ładujących powinni zarejestrować 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. Przykładowe wartości to:
- 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 kanonicznychsystem_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 zrozumiałasubreason
.
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 sprawdzić 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.