Omówienie programu rozruchowego

Program rozruchowy to obraz zastrzeżonego oprogramowania dostawcy, który odpowiada za wczytywanie jądra na urządzeniu. Bootloader chroni stan urządzenia i odpowiada za inicjowanie zaufanego środowiska wykonawczego (TEE) oraz wiązanie jego zaufanego źródła. Bootloader sprawdza integralność partycji boot i recovery, zanim przekaże sterowanie jądrze.

Przykładowy proces uruchamiania

Oto przykładowy proces uruchamiania:

  1. wczytać i inicjializować pamięć;

  2. Zweryfikuj urządzenie zgodnie z procedurą zweryfikowanego uruchamiania.

  3. Sprawdź partycje rozruchowe, w tym boot, dtbo, init_boot i recovery, zgodnie z procesem weryfikacji podczas uruchamiania. W ramach tego kroku sprawdź wersję nagłówka obrazu rozruchu i odpowiednio przeanalizuj nagłówek.

  4. Jeśli używane są aktualizacje A/B, określ bieżący slot do załadowania.

  5. Określ, czy należy uruchomić tryb odzyskiwania. Więcej informacji znajdziesz w artykule Obsługa aktualizacji OTA.

  6. Załaduj obrazy rozruchowe, takie jak boot.img, vendor_boot.img, init_boot.img i inne obrazy rozruchowe sprzedawców. Te obrazy rozruchu zawierają obrazy jądra i pliku ram.

    1. Wczytaj ją do pamięci jako samouruchamiający się skompresowany plik binarny. Jądro dekompresuje się i rozpoczyna wykonywanie w pamięci.

    2. Załaduj do pamięci ramdiski i sekcję bootconfig, aby utworzyć initramfs.

Dodatkowe funkcje związane z bootloaderem

Oto lista dodatkowych funkcji związanych z bootloaderem, które możesz zaimplementować:

  • Nakładka drzewa urządzeń (DTO). Nakładka drzewa urządzenia umożliwia bootloaderowi obsługę różnych konfiguracji sprzętowych. DTO jest kompilowane w pliku danych drzewa urządzenia (DTB), który jest używany przez bootloader.

  • Losowanie adresów wirtualnych obrazów jądra. Bootloader obsługuje losowanie adresu wirtualnego, pod który wczytywane jest jądro. Aby losować adres, ustaw RANDOMIZE_BASE na true w konfiguracji jądra. Program rozruchowy musi zapewnić entropię, przekazując losową wartość u64 w węźle drzewa urządzenia /chosen/kaslr-seed.

  • Weryfikacja podczas uruchamiania. Weryfikacja podczas uruchamiania pozwala ładownikowi upewnić się, że cały uruchamiany kod pochodzi z zaufanego źródła.

  • Konfiguracja rozruchu Konfiguracja rozruchu jest dostępna w Androidzie 12 i nowszych wersjach. Jest to mechanizm przekazywania szczegółów konfiguracji z kompilacji i ładowarki do systemu operacyjnego. W wersjach Androida 12 i starszych używane są parametry wiersza poleceń jądra z prefiksem androidboot.

  • Aktualizacje bezprzewodowe. Urządzenia z Androidem w polu mogą otrzymywać i instalować aktualizacje OTA systemu, aplikacji i reguł stref czasowych. Ta funkcja ma wpływ na implementację bootloadera. Ogólne informacje o OTA znajdziesz w artykule Aktualizacje OTA. Szczegółowe informacje o wdrożeniu aktualizacji OTA dotyczące programu rozruchowego znajdziesz w artykule Obsługa aktualizacji OTA.

  • Powiązanie z wersją. Powiązanie z wersją łączy klucze zabezpieczeń z systemem operacyjnym i poziomem aktualizacji zabezpieczeń. Powiązanie z wersją zapewnia, że atakujący, który odkryje słabość w starszej wersji systemu lub oprogramowania TEE, nie będzie mógł przywrócić urządzenia do wersji podatnej na ataki i używać kluczy utworzonych w nowszej wersji. Program rozruchowy musi zawierać określone informacje, aby obsługiwać wiązanie wersji. Więcej informacji znajdziesz w artykule Informacje o wersji w właściwościach AVB.

Wiersz poleceń jądra

Połącz wiersz poleceń jądra z tych lokalizacji:

  • Wiersz poleceń programu rozruchowego: zbiór parametrów statycznych i dynamicznych określonych przez program rozruchowy.

  • Drzewo urządzeń: z węzła chosen/bootargs

  • defconfig: z CONFIG_CMDLINE

  • boot.img: z wiersza poleceń (informacje o przesunięciu i rozmiarze znajdziesz w pliku system/core/mkbootimg/bootimg.h

Od Androida 12 w przypadku parametrów androidboot.*, które musimy przekazać do przestrzeni użytkownika Androida, możemy używać pliku bootconfig zamiast wiersza poleceń jądra.