Kanoniczny powód uruchamiania

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).initbootloader_boot_reason_propro.boot.bootreasonandroidboot.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.
  • 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 jak bootstatinit), 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ść z bootloader_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ęp detail 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. detailmoże wskazywać podsystem, aby ułatwić określenie, który konkretny system spowodował subreason. Możesz określić wiele wartości detail, które powinny być uporządkowane według hierarchii ważności. Możesz jednak zgłosić kilka wartości detail o równym znaczeniu.

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 i ramoops powinien zachować trwałe treści.
    • "warm". Ogólnie oznacza to, że pamięć i urządzenia zachowują pewien stan, a pamięć podręczna ramoops (patrz: pstore driver w rdzeniu) zawiera treści trwałe.
    • "shutdown"
    • "reboot". Oznacza to, że stan ramoops jest nieznany, a stan sprzętu jest nieznany. Jest to uniwersalna wartość, ponieważ wartości cold, hard i warm 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 kBootReasonMapsystem/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ątem kernel_panic signatures, aby doprecyzować przyczyny podrzędne w kanonicznym system_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 doprecyzowania reason.

Jeśli na przykład kBootReasonMap zawiera "wdog_bark", deweloper programu rozruchowego powinien:

  • Zmień na "watchdog,bark" i dodaj do listy w kBootReasonMap.
  • Zastanów się, co oznacza "bark" dla osób, które nie znają tej technologii, i sprawdź, czy dostępna jest bardziej odpowiednia subreason.

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.