Android 9 zawiera te zmiany w specyfikacji przyczyny rozruchu programu ładującego:
Przyczyny uruchomienia
Program rozruchowy używa unikalnych zasobów sprzętowych i pamięci, aby określić, dlaczego urządzenie zostało ponownie uruchomione, a następnie przekazuje tę informację, dodając androidboot.bootreason=<reason> do wiersza poleceń jądra Androida podczas uruchamiania. init następnie tłumaczy ten wiersz poleceń, aby przekazać go do właściwości Androida bootloader_boot_reason_prop (ro.boot.bootreason). W przypadku urządzeń wprowadzanych na rynek z Androidem 12 lub nowszym, które korzystają z wersji jądra 5.10 lub nowszej, do konfiguracji rozruchu dodawany jest parametr androidboot.bootreason=<reason> zamiast wiersza poleceń jądra.
Specyfikacje przyczyny uruchomienia
W poprzednich wersjach Androida określono format przyczyny rozruchu, który nie zawierał spacji, był pisany małymi literami i miał niewiele wymagań (np. w przypadku raportowania kernel_panic, watchdog, cold/warm/hard) oraz uwzględniał inne unikalne przyczyny. Ta luźna specyfikacja spowodowała rozpowszechnienie setek niestandardowych (a czasami bezsensownych) ciągów znaków przyczyny rozruchu, co z kolei doprowadziło do sytuacji nie do opanowania. W obecnej wersji Androida ogromna ilość niemal nieczytelnych lub bezsensownych treści zgłaszanych przez program rozruchowy spowodowała problemy z zgodnością w przypadku bootloader_boot_reason_prop.
W Androidzie 9 zespół Androida uznał, że starszy interfejs bootloader_boot_reason_prop ma duże znaczenie i nie można go ponownie napisać w czasie działania. Wszelkie ulepszenia specyfikacji przyczyny rozruchu muszą zatem wynikać z interakcji z programistami programów rozruchowych i dostosowywania istniejącego systemu. W tym celu zespół Androida:
- Nawiązywanie kontaktu z deweloperami programów rozruchowych, aby zachęcić ich do:
- Podaj kanoniczne, rozpoznawalne i łatwe do przeanalizowania przyczyny
bootloader_boot_reason_prop. - Uczestniczyć w
system/core/bootstat/bootstat.cppkBootReasonMap.
- Podaj kanoniczne, rozpoznawalne i łatwe do przeanalizowania przyczyny
- Dodanie kontrolowanego i przepisywalnego w czasie działania źródła
system_boot_reason_prop(sys.boot.reason). Ograniczony zestaw aplikacji systemowych (np.bootstatiinit) może przepisywać tę właściwość, ale wszystkie aplikacje mogą mieć przyznane uprawnienia sepolicy do jej odczytywania. - Informowanie użytkowników o przyczynie rozruchu, aby poczekać, aż dane użytkownika zostaną zamontowane, zanim zaufasz treści we właściwości przyczyny rozruchu systemu.
system_boot_reason_prop
Dlaczego tak późno? Chociaż bootloader_boot_reason_prop jest dostępny na wczesnym etapie rozruchu, jest blokowany przez zasady bezpieczeństwa Androida w miarę potrzeby, ponieważ reprezentuje nieprawidłowe, nieczytelne i niekanoniczne informacje.
W większości przypadków dostęp do tych informacji powinni mieć tylko deweloperzy z dogłębną wiedzą o systemie rozruchowym. Ulepszony, analizowalny i kanoniczny interfejs API dotyczący przyczyny rozruchu z system_boot_reason_prop można niezawodnie i dokładnie pobrać dopiero po zamontowaniu danych użytkownika.
Więcej szczegółów:
- Zanim dane użytkownika zostaną zamontowane, zmienna
system_boot_reason_propbędzie zawierać wartość z zmiennejbootloader_boot_reason_prop. - Po zamontowaniu danych o użytkownikach
system_boot_reason_propmoże zostać zaktualizowany, aby zachować zgodność lub przekazywać dokładniejsze informacje.
Z tego powodu Android 9 wydłuża okres, po którym można oficjalnie uzyskać przyczynę rozruchu. Zmienia go z natychmiastowej dokładności podczas rozruchu (z użyciem bootloader_boot_reason_prop) na dostępność dopiero po zamontowaniu danych użytkownika (z użyciem system_boot_reason_prop).
Logika Bootstat zależy od bardziej informacyjnego i zgodnego z przepisami bootloader_boot_reason_prop. Jeśli ta właściwość używa przewidywalnego formatu, zwiększa to dokładność wszystkich scenariuszy kontrolowanego ponownego uruchamiania i zamykania, co z kolei poprawia i rozszerza dokładność oraz znaczenie system_boot_reason_prop.
Kanoniczny format przyczyny uruchomienia
Kanoniczny format przyczyny rozruchu w przypadku bootloader_boot_reason_prop
w Androidzie 9 ma następującą składnię:
<reason>,<subreason>,<detail>…
Reguły formatowania:
- Małe litery
- Bez spacji (użyj podkreślenia)
- Wszystkie znaki drukowalne
- Rozdzielone przecinkami instancje
reason,subreasoni co najmniej jedna instancjadetail.- Wymagany element
reason, który reprezentuje powód o najwyższym priorytecie, dla którego urządzenie musiało zostać ponownie uruchomione lub wyłączone. - Opcjonalny element
subreason, który zawiera krótkie podsumowanie przyczyny ponownego uruchomienia lub wyłączenia urządzenia (lub informację o tym, kto je ponownie uruchomił lub wyłączył). - Co najmniej 1 opcjonalna wartość
detail. Poledetailmoże wskazywać podsystem, co ułatwia określenie, który konkretny system spowodował wystąpieniesubreason. Możesz podać wiele wartościdetail, które powinny być uporządkowane według ważności. Można jednak podawać kilka wartościdetailo równym znaczeniu.
- Wymagany element
Pusta wartość atrybutu bootloader_boot_reason_prop jest uznawana za nieprawidłową (ponieważ umożliwia innym agentom późniejsze wstawienie przyczyny uruchomienia).
Wymagania dotyczące uzasadnienia
Wartość podana w polu reason (pierwszy zakres, przed zakończeniem lub przecinkiem) musi należeć do jednego z tych zbiorów podzielonych na przyczyny podstawowe, istotne i ogólne:
- kernel set:
- „
watchdog" "kernel_panic"
- „
- silny zestaw:
"recovery""bootloader"
- blunt set:
"cold". Zwykle oznacza pełne zresetowanie wszystkich urządzeń, w tym pamięci."hard". Zwykle oznacza, że sprzęt został zresetowany, aramoopspowinien zachować trwałe treści."warm". Zwykle oznacza, że pamięć i urządzenia zachowują pewien stan, aramoops(patrzpstoresterownik w jądrze) zawiera trwałe treści."shutdown""reboot"Oznacza to, że stanramoopsjest nieznany, a stan sprzętu jest nieznany. Ta wartość jest ogólna, ponieważ wartościcold,hardiwarmwskazują, jak głębokie jest resetowanie urządzenia.
Programy rozruchowe muszą udostępniać zestaw jądra lub zestaw blunt reason i zdecydowanie zaleca się, aby w miarę możliwości udostępniały subreason. Na przykład długie naciśnięcie przycisku zasilania, które może mieć lub nie mieć ramoopskopii zapasowej, będzie miało przyczynę rozruchu "reboot,longkey".
Żaden pierwszy zakres reason nie może być częścią żadnego zakresu subreason ani detail. Jednak ponieważ przyczyny ustawione przez jądro nie mogą być generowane przez przestrzeń użytkownika, po ustawieniu przyczyny w sposób bezpośredni można ponownie użyć wartości "watchdog", podając szczegóły źródła (np. "reboot,watchdog,service_manager_unresponsive" lub "reboot,software,watchdog").
Przyczyny uruchomienia nie powinny wymagać specjalistycznej wiedzy wewnętrznej do rozszyfrowania ani powinny być czytelne dla człowieka i zawierać intuicyjny raport. Przykłady:"shutdown,vbxd" (źle), "shutdown,uv" (lepiej), "shutdown,undervoltage" (najlepiej).
Kombinacje przyczyna – podprzyczyna
Android rezerwuje zestaw kombinacji reason–subreason, których nie należy przeciążać w normalnym użytkowaniu, ale można ich używać w poszczególnych przypadkach, jeśli kombinacja dokładnie odzwierciedla powiązany warunek. Przykłady zarezerwowanych kombinacji:
"reboot,userrequested""shutdown,userrequested""shutdown,thermal"(z:thermald)"shutdown,battery""shutdown,battery,thermal"(zBatteryStatsService)"reboot,adb""reboot,shell""reboot,bootloader""reboot,recovery"
Więcej informacji znajdziesz w kBootReasonMapsystem/core/bootstat/bootstat.cpp i powiązanej historii zmian w repozytorium kodu źródłowego Androida.
Zgłaszanie przyczyn uruchomienia
Wszystkie przyczyny uruchomienia, zarówno z programu rozruchowego, jak i zarejestrowane w kanonicznej przyczynie uruchomienia, muszą być zapisane w sekcji kBootReasonMap pliku system/core/bootstat/bootstat.cpp. Lista kBootReasonMap zawiera zarówno przyczyny zgodne z zasadami, jak i przyczyny niezgodne z zasadami starszego typu. Deweloperzy programów rozruchowych powinni rejestrować tutaj tylko nowe powody zgodności (i nie powinni rejestrować powodów niezgodności, chyba że produkt został już wysłany i nie można go zmienić).
Zdecydowanie zalecamy korzystanie z istniejących, zgodnych wpisów w system/core/bootstat/bootstat.cpp i zachowanie ostrożności przed użyciem niezgodnego ciągu znaków. Zgodnie z wytycznymi:
- OK, aby zgłosić
"kernel_panic"z programu rozruchowego, ponieważbootstatmoże sprawdzićramoopspod kątemkernel_panic signatures, aby doprecyzować przyczyny dodatkowe do kanonicznej wartościsystem_boot_reason_prop. - Not OK, aby zgłosić ciąg znaków niezgodny z zasadami w
kBootReasonMap(np."panic")z programu rozruchowego, ponieważ ostatecznie uniemożliwi to doprecyzowaniereason).
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 znacząca wartośćsubreason.
Sprawdzanie zgodności przyczyny uruchomienia
Obecnie Android nie udostępnia aktywnego testu CTS, który mógłby dokładnie wywoływać lub sprawdzać wszystkie możliwe przyczyny uruchomienia, jakie może podać program rozruchowy. Partnerzy mogą jednak spróbować przeprowadzić test pasywny, aby określić zgodność.
W związku z tym zgodność z programem rozruchowym wymaga od deweloperów programów rozruchowych dobrowolnego przestrzegania ducha zasad i wytycznych opisanych powyżej.
Zachęcamy takich deweloperów do współtworzenia AOSP (zwłaszcza system/core/bootstat/bootstat.cpp) i wykorzystania tej okazji jako forum do dyskusji o problemach z przyczyną rozruchu.