Przenieś szybki rozruch do przestrzeni użytkownika

Fastboot to nazwa modułu i trybu Fastboot. Android 10 i nowsze wersje obsługują partycje o zmiennym rozmiarze dzięki przenoszeniu implementacji fastboot z bootloadera do przestrzeni użytkownika. Ta zmiana umożliwia przeniesienie kodu do obsługiwania oprogramowania do wspólnej, łatwej do utrzymania i testowania lokalizacji, w której znajdują się tylko elementy fastboot specyficzne dla danego producenta, implementowane przez warstwę abstrakcji sprzętowej (HAL). Dodatkowo Android 12 i nowsze wersje obsługują flashowanie dysków RAM za pomocą dodatkowej komendy fastboot.

Połączenie Fastboot i odzyskiwania

Ponieważ fastboot i odzyskiwanie w przestrzeni użytkownika są podobne, możesz je scalić w jedną partycję lub binarne. Daje to takie korzyści jak mniejsze zużycie miejsca, mniej partycji i wspólne korzystanie przez fastboot i recovery z jądra i bibliotek.

Fastbootd to nazwa demona i trybu w przestrzeni użytkownika. Aby obsługiwać fastbootd, program rozruchowy musi zaimplementować nowe polecenie bloku sterowania rozruchem (BCB) o nazwie boot-fastboot. Aby przejść do trybu fastbootd, bootloader zapisuje wartość boot-fastboot w polu polecenia wiadomości BCB i nie zmienia pola recovery wiadomości BCB (aby umożliwić ponowne uruchomienie przerwanych zadań odzyskiwania). Pola status, stagereserved również pozostają niezmienione. Po wykryciu boot-fastboot w polu polecenia BCB bootloader wczytuje obraz odzyskiwania i uruchamia go. Następnie odzyskiwanie analizuje wiadomość BCB i przełącza się w tryb fastbootd.

Polecenia ADB

W tej sekcji opisaliśmy komendę adb służącą do integracji fastbootd. Ten rozkaz ma różne wyniki w zależności od tego, czy jest wykonywany przez system czy przez odzyskiwanie.

Polecenie Opis
reboot fastboot
  • Uruchom ponownie fastbootd (system).
  • Wchodzi bezpośrednio do fastbootd bez restartu (przywracanie).

Polecenia fastboot

W tej sekcji opisano polecenia fastboot służące do integracji fastbootd, w tym nowe polecenia do flashowania i zarządzania partycjami logicznymi. Niektóre polecenia dają różne wyniki w zależności od tego, czy są wykonywane przez bootloader czy przez fastbootd.

Polecenie Opis
reboot recovery
  • Uruchom ponownie w trybie odzyskiwania (bootloader).
  • Wchodzi w tryb przywracania bezpośrednio bez ponownego uruchamiania (fastbootd).
reboot fastboot Uruchom ponownie fastbootd.
getvar is-userspace
  • Zwraca yes (fastbootd).
  • Zwraca no (program rozruchowy).
getvar is-logical:<partition> Zwraca yes, jeśli dana partycja jest partycją logiczną, a w przeciwnym razie zwraca no. Partycje logiczne obsługują wszystkie polecenia wymienione poniżej.
getvar super-partition-name Zwraca nazwę superpartycji. Nazwa zawiera podwójny sufiks, jeśli superpartycja jest partycją A/B (zazwyczaj tak nie jest).
create-logical-partition <partition> <size> Tworzy partycję logiczną o określonej nazwie i rozmiarze. Nazwa nie może już występować jako partycja logiczna.
delete-logical-partition <partition> Usuwa daną partycję logiczną (skutecznie usuwa partycję).
resize-logical-partition <partition> <size> Zmienia rozmiar partycji logicznej na nowy, nie zmieniając jej zawartości. Nie powiedzie się, jeśli nie ma wystarczającej ilości miejsca na zmianę rozmiaru.
flash <partition><filename> ] Zapisuje plik na partycji flash. Urządzenie musi być odblokowane.
erase <partition> Wymazuje partycję (nie musi być to bezpieczne czyszczenie). Urządzenie musi być odblokowane.
getvar <variable> | all Wyświetla zmienną bootloadera lub wszystkie zmienne. Jeśli zmienna nie istnieje, zwracany jest błąd.
set_active <slot>

Ustawia dany slot uruchamiania A/B jako active. Podczas następnej próby uruchomienia system uruchamia się z wybranego gniazda.

W przypadku obsługi A/B sloty to powielone zestawy partycji, które można uruchamiać niezależnie. Slots mają nazwy a, b itd. i są rozróżniane przez dodanie do nazwy partycji sufiksu _a, _b itd.

reboot Uruchom ponownie urządzenie.
reboot-bootloader (lub reboot bootloader) Uruchom ponownie urządzenie w trybie bootloadera.
fastboot fetch vendor_boot <out.img>

Używaj w Androidzie 12 i nowszych, aby obsługiwać flashowanie z ramdysk dostawcy.

Pobiera rozmiar całej partycji i rozmiar fragmentu. Pobiera dane z każdego fragmentu, a potem zszywał je w <out.img>

Więcej informacji znajdziesz w sekcji fastboot fetch vendor_boot <out.img>.

fastboot flash vendor_boot:default <vendor-ramdisk.img>

Używaj w Androidzie 12 i nowszych, aby obsługiwać flashowanie ramdysków dostawców.

To jest specjalny wariant polecenia flash. Wykonuje funkcję obrazu fetch vendor_boot tak, jakby wywołano funkcję fastboot fetch. Nowy obraz vendor_boot, który jest instalowany, zależy od tego, czy wersja nagłówka rozruchowego to wersja 3 czy 4.

Więcej informacji znajdziesz w sekcji fastboot flash vendor_boot:default <vendor-ramdisk.img>.

fastboot flash vendor_boot:<foo> <vendor-ramdisk.img> Używaj w Androidzie 12 i nowszych, aby obsługiwać flashowanie ramdysków dostawcy.

Pobiera obraz vendor_boot. Zwraca błąd, jeśli nagłówek rozruchu dostawcy ma wersję 3. Jeśli jest to wersja 4, znajduje odpowiedni fragment pamięci RAM dostawcy (jeśli jest dostępny). Zastępuje go określonym obrazem, ponownie oblicza rozmiary i przesunięcia oraz wyświetla nowy vendor_boot image.

Więcej informacji znajdziesz w sekcji fastboot flash vendor_boot:<foo> <vendor-ramdisk.img>.

Fastboot i program rozruchowy

Program rozruchowy aktualizuje partycje bootloader, radioboot/recovery, po czym urządzenie uruchamia się w trybie fastboot (przestrzeń użytkownika) i aktualizuje wszystkie pozostałe partycje. Program rozruchowy powinien obsługiwać te polecenia.

Polecenie Opis
download Pobiera obraz do flasha.
flash recovery <image>/ flash boot <image>/ flash bootloader <image>/ Flashes recovery/boot partition and bootloader.
reboot Uruchom ponownie urządzenie.
reboot fastboot Uruchom ponownie w trybie Fastboot.
reboot recovery Uruchom ponownie w trybie odzyskiwania.
getvar Pobiera zmienną programu rozruchowego, która jest wymagana do zaprogramowania obrazu odzyskiwania/rozruchu (na przykład current-slotmax-download-size).
oem <command> Polecenie zdefiniowane przez producenta OEM.

Dynamiczne partycje

Bootloader nie może zezwalać na flashowanie ani kasowanie partycji dynamicznych. W przypadku próby wykonania tych operacji musi zwracać błąd. W przypadku urządzeń z dynamiczną partycją, w których zastosowano starsze oprogramowanie, narzędzie fastboot (i program rozruchowy) obsługuje tryb wymuszania, aby bezpośrednio zaflashować dynamiczną partycję w trybie programu rozruchowego. Jeśli na przykład system to dynamiczna partycja na urządzeniu z dodatkowymi funkcjami, użycie polecenia fastboot --force flash system spowoduje, że bootloader (zamiast fastbootd) sflashuje partycję.

Ładowanie w trybie wyłączenia

Jeśli urządzenie obsługuje ładowanie w trybie wyłączenia lub automatycznie uruchamia się w trybie specjalnym po podłączeniu do zasilania, implementacja polecenia fastboot oem off-mode-charge 0 musi pomijać te tryby specjalne, aby urządzenie uruchamiało się tak, jakby użytkownik nacisnął przycisk zasilania.

Fastboot OEM HAL

Aby całkowicie zastąpić fastboot bootloadera, fastboot musi obsługiwać wszystkie istniejące polecenia fastboot. Wiele z tych poleceń pochodzi od producentów OEM i jest udokumentowanych, ale wymagają niestandardowej implementacji. Wiele poleceń dla OEM nie jest zdokumentowanych. Aby obsługiwać takie polecenia, interfejs Fastboot HAL określa wymagane polecenia OEM. Producenci OEM mogą też wdrażać własne polecenia.

Definicja interfejsu Fastboot HAL:

import IFastbootLogger;

/**
 * IFastboot interface implements vendor specific fastboot commands.
 */
interface IFastboot {
    /**
     * Returns a bool indicating whether the bootloader is enforcing verified
     * boot.
     *
     * @return verifiedBootState True if the bootloader is enforcing verified
     * boot and False otherwise.
     */
    isVerifiedBootEnabled() generates (bool verifiedBootState);

    /**
     * Returns a bool indicating the off-mode-charge setting. If off-mode
     * charging is enabled, the device autoboots into a special mode when
     * power is applied.
     *
     * @return offModeChargeState True if the setting is enabled and False if
     * not.
     */
    isOffModeChargeEnabled() generates (bool offModeChargeState);

    /**
     * Returns the minimum battery voltage required for flashing in mV.
     *
     * @return batteryVoltage Minimum battery voltage (in mV) required for
     * flashing to be successful.
     */
    getBatteryVoltageFlashingThreshold() generates (int32_t batteryVoltage);

    /**
     * Returns the file system type of the partition. This is only required for
     * physical partitions that need to be wiped and reformatted.
     *
     * @return type Can be ext4, f2fs or raw.
     * @return result SUCCESS if the operation is successful,
     * FAILURE_UNKNOWN if the partition is invalid or does not require
     * reformatting.
     */
    getPartitionType(string partitionName) generates (FileSystemType type, Result result);

    /**
     * Executes a fastboot OEM command.
     *
     * @param oemCmd The oem command that is passed to the fastboot HAL.
     * @response result Returns the status SUCCESS if the operation is
     * successful,
     * INVALID_ARGUMENT for bad arguments,
     * FAILURE_UNKNOWN for an invalid/unsupported command.
     */
    doOemCommand(string oemCmd) generates (Result result);

};

Włączanie fastbootd

Aby włączyć fastbootd na urządzeniu:

  1. Dodaj fastbootd do PRODUCT_PACKAGES w device.mk: PRODUCT_PACKAGES += fastbootd.

  2. Upewnij się, że interfejs HAL fastboot, interfejs HAL kontroli rozruchu i interfejs HAL stanu są spakowane w ramach obrazu odzyskiwania.

  3. Dodaj uprawnienia SEPolicy wymagane przez fastbootd. Na przykład fastbootd wymaga dostępu do zapisu na partycji specyficznej dla urządzenia, aby móc ją sformatować. Ponadto implementacja interfejsu HAL fastboot może wymagać uprawnień związanych z danym urządzeniem.

Aby zweryfikować fastboot w przestrzeni użytkownika, uruchom pakiet testów dostawcy (VTS).

Ramdysk dostawcy do flashowania

Android 12 i nowsze wersje obsługują flashowanie pamięci RAM z dodatkowym poleceniem fastboot, które pobiera pełny obraz vendor_boot z urządzenia. To polecenie powoduje, że narzędzie fastboot po stronie hosta odczytuje nagłówek rozruchu dostawcy, ponownie utworzy obraz i sflashuje nowy obraz.

Aby pobrać pełny obraz vendor_boot, dodano polecenie fetch:vendor_boot zarówno do protokołu fastboot, jak i do implementacji fastboot w Androidzie 12. Pamiętaj, że fastbootd wdrożył tę funkcję, ale sam bootloader może tego nie zrobić. Producenci OEM mogą dodać polecenie fetch:vendor_boot do implementacji tego protokołu w bootloaderze. Jeśli jednak polecenie nie zostanie rozpoznane w trybie bootloadera, flashowanie poszczególnych dysków RAM dostawcy w trybie bootloadera nie jest obsługiwane przez dostawcę.

Zmiany w programie rozruchowym

Polecenia getvar:max-fetch-size i fetch:name są wdrażane w fastbootd. Aby obsługiwać flashowanie dysków RAM dostawcy w programie rozruchowym, musisz wdrożyć te 2 polecenia.

Zmiany dotyczące szybkiego uruchamiania

getvar:max-fetch-size jest podobny do max-download-size. Określa maksymalny rozmiar, jaki urządzenie może wysłać w jednym komunikacie DATA. Sterownik nie może pobrać rozmiaru większego niż ta wartość.

fetch:name[:offset[:size]] przeprowadza na urządzeniu serię kontroli. Jeśli wszystkie te warunki są spełnione, polecenie fetch:name[:offset[:size]] zwraca dane:

  • Urządzenie działa w wersji umożliwiającej debugowanie.
  • Urządzenie jest odblokowane (pomarańczowy stan uruchamiania).
  • Wybrana nazwa partycji to vendor_boot.
  • Wartość size mieści się w przedziale 0 < size <= max-fetch-size.

Po ich zweryfikowaniu funkcja fetch:name[:offset[:size]] zwraca rozmiar partycji i przesunięcie. Uwaga:

  • fetch:name jest odpowiednikiem funkcji fetch:name:0, która jest odpowiednikiem funkcji fetch:name:0:partition_size.
  • fetch:name:offset to tyle samo co fetch:name:offset:(partition_size - offset)

Dlatego fetch:name[:offset[:size]] = fetch:name:offset:(partition_size - offset).

Jeśli nie określono wartości offset ani partition_size (lub obu), używane są wartości domyślne, które w przypadku offset to 0, a w przypadku size to obliczona wartość partition_size - offset.

  • Podano przesunięcie, rozmiar nieokreślony: size = partition_size - offset
  • Żadna z nich nie jest określona: w obu przypadkach używane są wartości domyślne, size = partition_size to 0.

Na przykład fetch:foo pobiera całą partycję foo z przesunięciem 0.

Zmiany dotyczące kierowcy

Do narzędzia fastboot dodano polecenia, które umożliwiają wprowadzanie zmian w sterownikach. Każdy z nich jest połączony z pełną definicją w tabeli komend Fastboot.

  • fastboot fetch vendor_boot out.img

    • Połączenia getvar max-fetch-size, aby określić rozmiar fragmentu.
    • Wywołania getvar partition-size:vendor_boot[_a] służą do określenia rozmiaru całej partycji.
    • Połączenia fastboot fetch vendor_boot[_a]:offset:size dla każdego fragmentu. (Rozmiar fragmentu jest większy niż rozmiar vendor_boot, więc zwykle jest tylko 1 fragment).
    • Łączy dane w jeden zbiór danych, który jest zapisywany w pliku out.img.
  • fastboot flash vendor_boot:default vendor-ramdisk.img

    To jest specjalny wariant polecenia flash. Pobiera obraz vendor_boot, tak jakby wywołano funkcję fastboot fetch.

    • Jeśli boot dostawcy jest w wersji 3, wykonuje on te czynności:
      • Zastępuje pamięć RAM dostawcy określonym obrazem.
      • Błyska nowy obraz vendor_boot.
    • Jeśli nagłówek bootowania dostawcy ma wersję 4, to:
      • Zastępuje cały obraz dostawcy w pamięci RAM obrazem, dzięki czemu dany obraz staje się jedynym fragmentem obrazu vendor_boot dostawcy w pamięci RAM.
      • Ponownie oblicza rozmiar i przesunięcie w tabeli ramdisk dostawcy.
      • Błyska nowy obraz vendor_boot.
  • fastboot flash vendor_boot:foo vendor-ramdisk.img

    Pobiera wartość vendor_boot image, tak jakby wywołano funkcję fastboot fetch.

    • Jeśli nagłówek dostawcy ma wersję 3, zwracany jest błąd.
    • Jeśli nagłówek dostawcy w bootloaderze ma wersję 4, wykonuje te czynności:

      • Znajduje fragment ramdisk dostawcy o nazwie ramdisk_<var>&lt;foo></var>. Jeśli nie zostanie znaleziony element lub jeśli zostanie znalezione kilka takich elementów, zwracany jest błąd.
      • Zastępuje fragment dostawcy ramdisku obrazem.
      • Ponownie oblicza każdy rozmiar i przesunięcie w tabeli dostawcy ramdisk.
      • Błyska nowy obraz vendor_boot.
    • Jeśli <foo> nie jest określony, usługa próbuje znaleźć ramdisk_.

mkbootimg

Nazwa default jest zarezerwowana do nazywania fragmentów ramdisk dostawcy w Androidzie 12 i nowszych. Chociaż semantyka fastboot flash vendor_boot:default pozostaje taka sama, nie wolno nazywać fragmentów dysku RAM jako default.

Zmiany w SELinux

Wprowadziliśmy zmianę w fastbootd.te, aby umożliwić obsługę flashowania dysków RAM dostawcy.