Omówienie programu rozruchowego

Program rozruchowy to obraz własnościowy 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 też integralność partycji bootrecovery, zanim przekaże sterowanie jądrze.

Przykładowy proces uruchamiania

Oto przykładowy proces uruchamiania:

  1. wczytać i inicjializować pamięć;

  2. Sprawdź urządzenie zgodnie z procesem weryfikacji podczas 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. Wczytaj obrazy rozruchowe, takie jak boot.img, vendor_boot.img i init_boot.img, oraz inne zastrzeżone obrazy rozruchowe dostawcy. Te obrazy rozruchu zawierają obrazy jądra i pliku ram.

    1. Wczytaj ją do pamięci jako samodzielnie 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 programem rozruchowym

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 programowi rozruchowemu obsługę różnych konfiguracji sprzętowych. DTO jest łączone w plik blob drzewa urządzenia (DTB), który jest używany przez program rozruchowy.

  • losowania wirtualnego adresu jądra, Program rozruchowy obsługuje losowo wirtualny adres, pod którym wczytywany jest obraz jądra. 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 umożliwia programowi rozruchowemu zapewnienie, że cały wykonywany 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 terenie mogą otrzymywać i instalować aktualizacje OTA systemu, oprogramowania aplikacji i reguł strefy czasowej. Ta funkcja ma wpływ na implementację bootloadera. Ogólne informacje o aktualizacjach OTA znajdziesz w artykule Aktualizacje OTA. Szczegółowe informacje o implementacji OTA w przypadku konkretnego programu rozruchowego znajdziesz w artykule Obsługa aktualizacji OTA.

  • Powiązanie z wersją. Powiązanie wersji łączy klucze zabezpieczeń z systemem operacyjnym i poziomem poprawek. 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ęciach i rozmiarach znajdziesz w system/core/mkbootimg/bootimg.h

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