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 fastboota została przeniesiona z programu rozruchowego do przestrzeni użytkownika. Ta zmiana umożliwia przeniesienie kodu flashowania do wspólnej lokalizacji, którą można utrzymywać i testować. Tylko części fastboota specyficzne dla dostawcy są implementowane przez warstwę abstrakcji sprzętowej (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 zaimplementować 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 przywracania systemu i uruchamia go. Tryb przywracania analizuje wiadomość BCB i przełącza się w tryb fastbootd.

Polecenia ADB

W tej sekcji opisujemy polecenie adb służące do integracji 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
  • Uruchamia ponownie urządzenie w trybie odzyskiwania (program rozruchowy).
  • Włącza 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 przedział jest przedział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 gniazda, 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 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 rozruchowego lub wszystkie zmienne. Jeśli zmienna nie istnieje, zwraca błąd.
set_active <slot>

Ustawia podany slot rozruchowy A/B jako active. Przy następnej próbie uruchomienia system uruchomi się 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 <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żywana w Androidzie 12 i nowszym do obsługi flashowania dysków RAM dostawcy.

Pobiera obraz vendor_boot. Zwraca błąd, jeśli nagłówek rozruchowy dostawcy ma wersję 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

Program rozruchowy 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) sflashowanie 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 do 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 przywracania systemu.

  3. Dodaj uprawnienia SEPolicy specyficzne dla urządzenia wymagane przez fastbootd. Na przykład fastbootd wymaga uprawnień do zapisu w partycji 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, polecenie fetch:vendor_boot zostało dodane zarówno do protokołu fastboot, jak i do implementacji protokołu fastbootd w Androidzie 12. Pamiętaj, że fastbootd implementuje tę funkcję, ale sam program rozruchowy 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 programu rozruchowego, 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 oznaczony kolorem pomarańczowym).
  • Pobrana nazwa partycji to vendor_boot.
  • Wartość size mieści się w zakresie 0 < size <= max-fetch-size.

Po zweryfikowaniu tych informacji funkcja 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ównoważne z fetch:name:offset:(partition_size - offset)

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

Jeśli nie podasz wartości offset lub partition_size (lub obu tych wartości), zostaną użyte 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: w przypadku obu atrybutów używane są wartości domyślne, size = partition_size – 0.

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

Zmiany sterownikó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, 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 program rozruchowy dostawcy ma nagłówek 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 ma wersję 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 znaleziono dopasowania lub znaleziono ich kilka, zwraca błąd.
      • Zastępuje fragment ramdysku dostawcy podanym obrazem.
      • Ponownie oblicza każdy rozmiar i przesunięcie w tabeli dysku RAM dostawcy.
      • Wyświetla nowy obraz vendor_boot.
    • Jeśli nie podasz wartości <foo>, spróbuje znaleźć ramdisk_.

mkbootimg

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

Zmiany w SELinux

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