Kanoniczny powód uruchamiania

Android 9 zawiera poniższe zmiany w specyfikacji przyczyny uruchamiania programu rozruchowego.

Przyczyny 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. Następnie init tłumaczy ten wiersz poleceń tak, aby został rozpowszechniony na właściwość Androida bootloader_boot_reason_prop (ro.boot.bootreason). W przypadku urządzeń uruchamianych z Androidem 12 lub nowszym z użyciem jądra w wersji 5.10 lub nowszej do konfiguracji rozruchowej zamiast wiersza poleceń jądra dodawany jest ciąg androidboot.bootreason=<reason>.

Specyfikacja przyczyny uruchamiania

Poprzednie wersje Androida określały format przyczyny uruchamiania bez spacji, były w całości małymi literami, zawierały kilka wymagań (np. dotyczących raportowania kernel_panic, watchdog, cold/warm/hard), a także uwzględniały inne unikalne przyczyny. Ta luźna specyfikacja doprowadziła do upowszechnienia setek niestandardowych (i czasami bezsensownych) ciągów tekstowych przyczyn uruchamiania, co z kolei doprowadziło do powstania sytuacji, której nie da się zarządzać. W obecnej wersji Androida ogromne ilości treści niemal niemożliwych do przeanalizowania lub bezsensownych treści zgłaszanych przez program rozruchowy spowodowały problemy ze zgodnością wersji bootloader_boot_reason_prop.

W wersji Androida 9 zespół Androida zauważył, że starsza wersja bootloader_boot_reason_prop rozwija się bardzo szybko i nie można jej ponownie napisać w czasie działania. Wszelkie ulepszenia specyfikacji przyczyny uruchamiania muszą więc wynikać z interakcji z programistami programu rozruchowego i dostosowań do istniejącego systemu. W związku z tym zespół Androida:

  • Współpraca z deweloperami programu rozruchowego, aby zachęcić ich do:
    • Podaj kanoniczne, możliwe do przeanalizowania i rozpoznawalne przyczyny elementu bootloader_boot_reason_prop.
    • Znajdź się na liście system/core/bootstat/bootstat.cpp kBootReasonMap.
  • Dodanie kontrolowanego i możliwego do wielokrotnego zapisu źródła elementu system_boot_reason_prop (sys.boot.reason). Ograniczony zestaw aplikacji systemowych (np. bootstat i init) może przepisywać tę właściwość, ale wszystkim aplikacjom można przyznać uprawnienia do jej odczytu.
  • Informowanie użytkowników o przyczynie rozruchu przed oznaczeniem treści jako zaufanej we właściwości system_boot_reason_prop przyczyny rozruchu systemu, aż po podłączeniu danych użytkownika.

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. Dopracowany, możliwy do analizy i kanoniczny interfejs API z powodu uruchamiania z system_boot_reason_prop może być niezawodnie i dokładnie odebrany dopiero po podłączeniu danych użytkownika. Więcej szczegółów:

  • Przed podłączeniem danych użytkownika 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 przed oficjalnym uzyskaniem przyczyny rozruchu. Zmienia się on z natychmiastowej dokładności przy uruchamianiu (z funkcją bootloader_boot_reason_prop) na dostępny dopiero po podłączeniu danych użytkownika (za pomocą system_boot_reason_prop).

Logika Bootstat zależy od bardziej informacyjnego i zgodnego standardu bootloader_boot_reason_prop. Gdy ta usługa używa przewidywalnego formatu, zwiększa dokładność wszystkich scenariuszy kontrolowanego ponownego uruchamiania i wyłączania, co z kolei zwiększa dokładność i znaczenie funkcji system_boot_reason_prop.

Kanoniczny format przyczyny uruchamiania

Kanoniczny format przyczyny uruchamiania aplikacji bootloader_boot_reason_prop na Androidzie 9 ma tę składnię:

<reason>,<subreason>,<detail>…

Reguły formatowania:

  • Małe litery
  • Brak pustych pól (użyj podkreślenia)
  • Wszystkie znaki do wydrukowania
  • Rozdzielane przecinkami: reason, subreason i co najmniej 1 instancja detail.
    • Wymagany element reason, który reprezentuje przyczynę ponownego uruchomienia lub wyłączenia urządzenia o najwyższym priorytecie.
    • Opcjonalny obiekt subreason reprezentujący krótkie podsumowanie powodów, dla których urządzenie musi zostać zrestartowane lub wyłączone (albo kto je zrestartował lub wyłączył).
    • Co najmniej 1 opcjonalna wartość detail. Element detail może wskazywać podsystem, który ułatwia określenie, który konkretnie system spowodował wystąpienie subreason. Możesz podać wiele wartości detail, które zwykle są zgodne z hierarchią ważności. Możesz jednak zgłosić kilka wartości detail o równym znaczeniu.

Pusta wartość atrybutu bootloader_boot_reason_prop jest uznawana za niezgodną z prawem (pozwala to innym agentom wstrzyknąć powód rozruchu po fakcie).

Wymagania dotyczące powodów

Wartość podana w polu reason (pierwszy zakres, przed zakończeniem lub przecinkiem) musi należeć do poniższego zestawu z podziałem na jądro, silne i twarde przyczyny:

  • zestaw jądra:
    • watchdog"
    • "kernel_panic"
  • silny zestaw:
    • "recovery"
    • "bootloader"
  • zestaw tęczy:
    • "cold". Ogólnie oznacza pełny reset wszystkich urządzeń, w tym pamięci.
    • "hard". Ogólnie wskazuje, że stan sprzętu został zresetowany, a element ramoops powinien zachować trwałe treści.
    • "warm". Ogólnie wskazuje, że pamięć i urządzenia zachowują określony stan, a ramoops (sterownik pstore w magazynie jądra) zawiera trwałe treści.
    • "shutdown"
    • "reboot". Zwykle oznacza, ż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 klawisza zasilania, które może (ale nie musi) powodować utworzenie kopii zapasowej ramoops, ma przyczynę uruchamiania "reboot,longkey".

Pierwszy reason spanu nie może być częścią żadnej wartości subreason ani detail. Ponieważ jednak przyczyny zestawu jądra nie mogą być generowane przez przestrzeń użytkownika, można więc ponownie użyć właściwości "watchdog" po tym, jak wskazuje ona tępy zbiór danych, wraz ze szczegółami źródła (na przykład "reboot,watchdog,service_manager_unresponsive" lub "reboot,software,watchdog").

Powody rozruchu nie powinny wymagać specjalistycznej wiedzy wewnętrznej do rozszyfrowania ani powinny być zrozumiałe dla człowieka i dostępne w intuicyjnym raporcie. Przykłady: "shutdown,vbxd" (złe), "shutdown,uv" (lepsze), "shutdown,undervoltage" (preferowane).

Kombinacje przyczyny i podprzyczyna

Android rezerwuje zestaw kombinacji reasonsubreason, które nie powinny być przeciążone przy normalnym użytkowaniu, ale można ich używać zależnie od konkretnego przypadku, jeśli dana kombinacja dokładnie odzwierciedla powiązany warunek. Przykłady zarezerwowanych kombinacji:

  • "reboot,userrequested"
  • "shutdown,userrequested"
  • "shutdown,thermal" (z thermald)
  • "shutdown,battery"
  • "shutdown,battery,thermal" (od BatteryStatsService)
  • "reboot,adb"
  • "reboot,shell"
  • "reboot,bootloader"
  • "reboot,recovery"

Więcej informacji znajdziesz w sekcji kBootReasonMap w dokumencie system/core/bootstat/bootstat.cpp oraz w powiązanej historii zmian git w repozytorium źródłowym Androida.

Zgłoś przyczyny uruchamiania

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 to połączenie przyczyn niezgodności i starszych. Deweloperzy programu rozruchowego powinni rejestrować w tym miejscu tylko nowe przyczyny zgodności z zasadami (i nie powinni rejestrować przyczyn niezgodności produktu, 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 powstrzymanie się przed użyciem niezgodnego ciągu znaków. Oto co należy zrobić:

  • OK, aby zgłosić błąd "kernel_panic" z programu rozruchowego, ponieważ bootstat może sprawdzić ramoops dla elementu kernel_panic signatures, aby zawęzić przyczyny do kanonicznego system_boot_reason_prop.
  • Nie można zgłosić niezgodnego ciągu znaków w pliku kBootReasonMap (np. "panic") z programu rozruchowego, ponieważ uniemożliwi to doprecyzowanie reason).

Jeśli na przykład kBootReasonMap zawiera ciąg "wdog_bark", programista programu rozruchowego powinien:

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

Sprawdzanie zgodności przyczyny uruchamiania

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 udziału w programie AOSP (w szczególności dla platformy system/core/bootstat/bootstat.cpp) i do korzystania z tej możliwości jako forum do dyskusji na temat problemów z powodem uruchamiania.