Przenoszenie Fastboot do przestrzeni użytkownika

Fastboot to nazwa modułu i trybu programu rozruchowego. Android 10 i nowsze wersje obsługują partycje o zmiennej wielkości, ponieważ implementacja fastboot została przeniesiona z programu rozruchowego do przestrzeni użytkownika. Ta zmiana umożliwia przeniesienie kodu migającego do wspólnej lokalizacji, którą można utrzymywać i testować. Tylko części fastboota specyficzne dla dostawcy są implementowane przez warstwę abstrakcji sprzętu (HAL). Dodatkowo Android 12 i nowsze wersje obsługują flashowanie dysków RAM przez dodaną komendę fastboot.

Ujednolicenie trybu Fastboot i trybu recovery

Ponieważ fastboot i recovery w przestrzeni użytkownika są podobne, możesz je scalić w jedną partycję lub plik binarny. Daje to takie korzyści jak mniejsze zużycie miejsca, mniejsza liczba partycji oraz możliwość współdzielenia jądra i bibliotek przez fastboot i recovery.

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

Polecenia ADB

W tej sekcji opisujemy polecenie adb służące do integrowania fastbootd. Polecenie daje różne wyniki w zależności od tego, czy jest wykonywane przez system, czy przez odzyskiwanie.

Polecenie Opis
reboot fastboot
  • Uruchamia się ponownie w fastbootd (system).
  • Uruchamia fastbootd bezpośrednio bez ponownego uruchamiania (przywracania).

Polecenia Fastboot

W tej sekcji opisujemy polecenia fastboot 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 zostały wykonane przez program rozruchowy czy przez fastbootd.

Polecenie Opis
reboot recovery
  • Ponownie uruchamia urządzenie w trybie odzyskiwania (program rozruchowy).
  • Uruchamia tryb przywracania bezpośrednio bez ponownego uruchamiania (fastbootd).
reboot fastboot Uruchamia się ponownie w fastbootd.
getvar is-userspace
  • Zwroty yes (fastbootd).
  • Zwraca no (program rozruchowy).
getvar is-logical:<partition> Zwraca yes, jeśli podany podział jest podziałem logicznym, w przeciwnym razie zwraca no. Partycje logiczne obsługują wszystkie polecenia wymienione poniżej.
getvar super-partition-name Zwraca nazwę superpartycji. Nazwa zawiera bieżący sufiks slotu, jeśli superpartycja jest partycją A/B (zwykle tak nie jest).
create-logical-partition <partition> <size> Tworzy partycję logiczną o podanej nazwie i rozmiarze. Nazwa nie może już istnieć jako partycja logiczna.
delete-logical-partition <partition> Usuwa podaną partycję logiczną (w praktyce ją czyści).
resize-logical-partition <partition> <size> Zmienia rozmiar partycji logicznej na nowy rozmiar bez zmiany jej zawartości. Nie powiedzie się, jeśli nie ma wystarczającej ilości miejsca na zmianę rozmiaru.
flash <partition><filename> ] Zapisuje plik w partycji pamięci flash. Urządzenie musi być odblokowane.
erase <partition> Usuwa partycję (nie musi to być bezpieczne usuwanie). Urządzenie musi być odblokowane.
getvar <variable> | all Wyświetla zmienną programu ładującego lub wszystkie zmienne. Jeśli zmienna nie istnieje, zwraca błąd.
set_active <slot>

Ustawia podany slot rozruchu A/B jako active. Podczas kolejnej próby uruchomienia system zostanie uruchomiony z określonego gniazda.

W przypadku obsługi A/B gniazda to zduplikowane zestawy partycji, z których można uruchamiać system niezależnie. Gniazda mają nazwy a, b itd. i są rozróżniane przez dodanie do nazwy partycji sufiksów _a, _b itd.

reboot Normalnie uruchamia ponownie urządzenie.
reboot-bootloader (lub reboot bootloader) Uruchamia ponownie urządzenie w programie rozruchowym.
fastboot fetch vendor_boot <out.img>

Użyj w Androidzie 12 i nowszym, aby obsługiwać flashowanie ramdysków dostawcy.

Pobiera cały rozmiar partycji i rozmiar fragmentu. Pobiera dane z każdego fragmentu, a następnie łączy je w całość, aby <out.img>

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

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

Użyj w Androidzie 12 i nowszym, aby obsługiwać flashowanie dysków RAM dostawcy.

Jest to specjalny wariant polecenia flash. Wykonuje funkcję obrazu fetch vendor_boot, tak jakby wywołano funkcję fastboot fetch. Nowy obraz vendor_boot, który jest wyświetlany, zależy od tego, czy wersja nagłówka rozruchowego to 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żyj w Androidzie 12 i nowszym, aby obsługiwać flashowanie dysków RAM dostawcy.

Pobiera obraz vendor_boot. Zwraca błąd, jeśli nagłówek rozruchowy dostawcy jest w wersji 3. Jeśli jest to wersja 4, wyszukuje prawidłowy fragment ramdysku dostawcy (jeśli jest dostępny). Zastępuje go podanym 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 flashuje partycje bootloader, radioboot/recovery, po czym urządzenie uruchamia się w trybie fastboot (przestrzeń użytkownika) i flashuje wszystkie pozostałe partycje. Program rozruchowy powinien obsługiwać te polecenia.

Polecenie Opis
download Pobiera obraz do pamięci flash.
flash recovery <image>/ flash boot <image>/ flash bootloader <image>/ Wgrywa partycję recovery/boot i program rozruchowy.
reboot Uruchamia ponownie urządzenie.
reboot fastboot Uruchamia się ponownie w trybie Fastboot.
reboot recovery Uruchamia się ponownie w trybie odzyskiwania.
getvar Pobiera zmienną programu rozruchowego, która jest wymagana do flashowania obrazu odzyskiwania lub rozruchu (np. current-slotmax-download-size).
oem <command> Polecenie zdefiniowane przez producenta OEM.

Partycje dynamiczne

Bootloader nie może zezwalać na flashowanie ani usuwanie partycji dynamicznych i musi zwracać błąd, jeśli te operacje są podejmowane. W przypadku urządzeń z dynamicznymi partycjami, które zostały do nich dostosowane, narzędzie fastboot (i program rozruchowy) obsługuje tryb wymuszony, który umożliwia bezpośrednie flashowanie dynamicznej partycji w trybie programu rozruchowego. Jeśli na przykład system jest partycją dynamiczną na urządzeniu po modernizacji, użycie polecenia fastboot --force flash system umożliwia programowi ładującemu (zamiast fastbootd) zapisanie partycji.

Ładowanie w trybie wyłączonym

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

Warstwa HAL OEM Fastboot

Aby całkowicie zastąpić program rozruchowy fastboot, musi on obsługiwać wszystkie dotychczasowe polecenia fastboot. Wiele z tych poleceń pochodzi od producentów OEM i jest udokumentowanych, ale wymaga niestandardowego wdrożenia. Wiele poleceń specyficznych dla OEM nie jest udokumentowanych. Aby obsługiwać takie polecenia, HAL fastboot określa wymagane polecenia OEM. Producenci OEM mogą też wdrażać własne polecenia.

Definicja HAL fastboot jest następująca:

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. Dodano fastbootd do PRODUCT_PACKAGESdevice.mk: PRODUCT_PACKAGES += fastbootd.

  2. Upewnij się, że HAL fastboot, HAL sterowania rozruchem i HAL stanu urządzenia są spakowane jako część obrazu odzyskiwania.

  3. Dodaj uprawnienia SEPolicy specyficzne dla urządzenia wymagane przez fastbootd. Na przykład fastbootd wymaga uprawnień do zapisu w partycji specyficznej dla urządzenia, aby ją sflashować. Dodatkowo implementacja HAL fastboot może też wymagać uprawnień specyficznych dla urządzenia.

Aby sprawdzić działanie fastboot w przestrzeni użytkownika, uruchom Vendor Test Suite (VTS).

Obrazy dysków RAM dostawców pamięci flash

Android 12 i nowsze wersje obsługują miganie dysków RAM z dodatkowym poleceniem fastboot, które pobiera pełny obraz vendor_boot z urządzenia. Polecenie powoduje, że narzędzie fastboot po stronie hosta odczytuje nagłówek rozruchowy dostawcy, ponownie tworzy obraz i zapisuje nowy obraz.

Aby pobrać pełny obraz vendor_boot, do protokołu fastboot i implementacji protokołu fastbootd w Androidzie 12 dodano polecenie fetch:vendor_boot. Pamiętaj, że fastbootd implementuje tę funkcję, ale sam program ładujący może tego nie robić. Producenci OEM mogą dodać polecenie fetch:vendor_boot do implementacji programu rozruchowego protokołu. Jeśli jednak polecenie nie jest rozpoznawane w trybie bootloadera, flashowanie poszczególnych dysków RAM dostawcy w tym trybie nie jest opcją obsługiwaną przez dostawcę.

Zmiany w programie rozruchowym

Polecenia getvar:max-fetch-sizefetch:name są zaimplementowane w fastbootd. Aby obsługiwać flashowanie dysków RAM dostawcy w programie rozruchowym, musisz zaimplementować te 2 polecenia.

Zmiany w fastbootd

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

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

  • Urządzenie korzysta z kompilacji, którą można debugować.
  • Urządzenie jest odblokowane (stan uruchamiania jest pomarańczowy).
  • Pobrana nazwa partycji to vendor_boot.
  • Wartość size mieści się w zakresie 0 < size <= max-fetch-size.

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

  • Funkcja fetch:name jest odpowiednikiem funkcji fetch:name:0, która jest odpowiednikiem funkcji fetch:name:0:partition_size.
  • fetch:name:offset jest równoznaczne z 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 lub partition_size (lub obu tych wartości), używane są wartości domyślne, czyli 0 w przypadku offset i obliczona wartość partition_size - offset w przypadku size.

  • Określono przesunięcie, ale nie rozmiar: size = partition_size - offset
  • Nie podano żadnej wartości: używane są wartości domyślne dla obu atrybutów, size = partition_size – 0.

Na przykład fetch:foo pobiera cały partycjonowany zbiór foo z przesunięciem 0.

Zmiany kierowców

Do narzędzia fastboot dodano polecenia umożliwiające wprowadzanie zmian w sterownikach. Każda z nich jest połączona z pełną definicją w tabeli poleceń Fastboot.

  • fastboot fetch vendor_boot out.img

    • Wywołuje funkcję Calls getvar max-fetch-size, aby określić rozmiar fragmentu.
    • Wywołuje funkcję getvar partition-size:vendor_boot[_a], aby określić rozmiar całej partycji.
    • Wywołuje funkcję fastboot fetch vendor_boot[_a]:offset:size dla każdego fragmentu. (Rozmiar fragmentu jest większy niż vendor_boot, więc zwykle jest tylko jeden fragment).
    • Łączy dane w całość, aby out.img.
  • fastboot flash vendor_boot:default vendor-ramdisk.img

    Jest to specjalny wariant polecenia flash. Pobiera obraz vendor_boot, tak jakby wywołano fastboot fetch.

    • Jeśli rozruch dostawcy jest nagłówkiem wersji 3, wykonuje te czynności:
      • Zastępuje dysk RAM dostawcy podanym obrazem.
      • Wyświetla nowy obraz vendor_boot.
    • Jeśli nagłówek rozruchowy dostawcy ma wersję 4, wykonuje te czynności:
      • Zastępuje cały dysk RAM dostawcy podanym obrazem, tak aby podany obraz stał się jedynym fragmentem dysku RAM dostawcy w obrazie vendor_boot.
      • Ponownie oblicza rozmiar i przesunięcie w tabeli dysku RAM dostawcy.
      • Wyświetla nowy obraz vendor_boot.
  • fastboot flash vendor_boot:foo vendor-ramdisk.img

    Pobiera vendor_boot image, tak jakby wywołano fastboot fetch.

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

      • Znajduje fragment dysku RAM dostawcy o nazwie ramdisk_<var>&lt;foo></var>. Jeśli nie zostanie znaleziony lub jeśli będzie wiele dopasowań, zwraca błąd.
      • Zastępuje fragment ramdysku dostawcy podanym obrazem.
      • Ponownie oblicza każdy rozmiar i przesunięcie w tabeli ramdysku dostawcy.
      • Wyświetla nowy obraz vendor_boot.
    • Jeśli nie podasz wartości <foo>, spróbuje znaleźć wartość ramdisk_.

mkbootimg

Nazwa default jest zarezerwowana dla fragmentów dysku RAM dostawcy w Androidzie 12 i nowszych wersjach. Semantyka fastboot flash vendor_boot:defaultpozostaje bez zmian, ale fragmenty ramdysku nie mogą mieć nazwy default.

Zmiany w SELinux

Wprowadzono zmianę w  fastbootd.te w celu obsługi flashowania dysków RAM dostawców.