Układ partycji

W systemie Android 10 główny system plików nie jest już zawarty w ramdisk.img i zamiast tego jest scalony z system.img (tzn. system.img jest zawsze tworzony tak, jakby ustawiono BOARD_BUILD_SYSTEM_ROOT_IMAGE ). Urządzenia uruchamiane z systemem Android 10:

  • Użyj układu partycji systemowej jako root (automatycznie wymuszanego przez kompilację bez opcji zmiany zachowania).
  • Należy używać ramdysku, który jest wymagany w przypadku dm-linear.
  • Należy ustawić BOARD_BUILD_SYSTEM_ROOT_IMAGE na false . To ustawienie służy jedynie do rozróżnienia urządzeń korzystających z ramdysku od urządzeń, które nie korzystają z ramdysku (zamiast tego montują bezpośrednio plik system.img ).

Znaczenie konfiguracji systemu jako root jest inne w przypadku systemów Android 9 i Android 10. W przypadku konfiguracji systemu jako root w systemie Android 9 zmienna BOARD_BUILD_SYSTEM_ROOT_IMAGE ma wartość true , co wymusza na kompilacji połączenie głównego systemu plików z system.img zamontuj system.img jako główny system plików (rootfs). Ta konfiguracja jest obowiązkowa w przypadku urządzeń z systemem Android 9, ale jest opcjonalna w przypadku urządzeń uaktualniających do Androida 9 i urządzeń z niższymi wersjami Androida. W konfiguracji systemu Android 10 jako root kompilacja zawsze łączy $TARGET_SYSTEM_OUT i $TARGET_ROOT_OUT w system.img ; ta konfiguracja jest domyślnym zachowaniem dla wszystkich urządzeń z systemem Android 10.

W systemie Android 10 wprowadzane są dalsze zmiany w obsłudze partycji dynamicznych – systemu partycjonowania przestrzeni użytkownika, który umożliwia aktualizacje bezprzewodowe (OTA) w celu tworzenia, zmiany rozmiaru lub niszczenia partycji. W ramach tej zmiany jądro Linuksa nie może już montować logicznej partycji systemowej na urządzeniach z systemem Android 10, dlatego operację tę obsługuje init pierwszego etapu.

Poniższe sekcje opisują wymagania systemu jako root dla systemowych OTA, zawierają wskazówki dotyczące aktualizacji urządzeń w celu korzystania z systemu jako root (w tym zmiany układu partycji i wymagania jądra dm-verity). Aby uzyskać szczegółowe informacje na temat zmian w ramdysku, zobacz Partycje Ramdysku .

Informacje o systemowych OTA

Systemowe OTA, które umożliwiają wersjom Androida aktualizację plików system.img i product.img bez zmiany innych partycji, wymagają układu partycji systemowej jako root. Wszystkie urządzenia z systemem Android 10 muszą korzystać z układu partycji typu system jako root, aby umożliwić korzystanie wyłącznie z systemu OTA.

Aby uzyskać szczegółowe informacje na temat urządzeń A/B i innych niż A/B, zobacz Aktualizacje systemu A/B (bezproblemowe) .

Korzystanie z nakładki dostawcy

Nakładka dostawcy umożliwia nałożenie zmian na partycję vendor podczas uruchamiania urządzenia. Nakładka dostawcy to zestaw modułów dostawcy w partycji product , które są nakładane na partycję vendor podczas uruchamiania urządzenia, zastępując i dodając istniejące moduły.

Po uruchomieniu urządzenia proces init kończy pierwszy etap montowania i odczytuje właściwości domyślne. Następnie przeszukuje /product/vendor_overlay/<target_vendor_version> i montuje każdy podkatalog w odpowiadającym mu katalogu partycji vendor , jeśli spełnione są następujące warunki:

  • /vendor/<overlay_dir> istnieje.
  • /product/vendor_overlay/<target_vendor_version>/<overlay_dir> ma ten sam kontekst pliku co /vendor/<overlay_dir> .
  • init może być montowany w kontekście pliku /vendor/<overlay_dir> .

Implementacja nakładki dostawcy

Zainstaluj pliki nakładki dostawcy w /product/vendor_overlay/<target_vendor_version> . Pliki te nakładają się na partycję vendor podczas uruchamiania urządzenia, zastępując pliki o tej samej nazwie i dodając nowe. Nakładka dostawcy nie może usunąć plików z partycji vendor .

Pliki nakładek dostawcy muszą mieć ten sam kontekst pliku, co pliki docelowe, które zastępują na partycji vendor . Domyślnie pliki w katalogu /product/vendor_overlay/<target_vendor_version> mają kontekst vendor_file . Jeśli istnieją niezgodności kontekstu plików między plikami nakładek dostawcy a plikami, które zastępują, określ to w polityce specyficznej dla urządzenia. Kontekst pliku jest ustawiany na poziomie katalogu. Jeśli kontekst pliku w katalogu nakładkowym dostawcy nie jest zgodny z katalogiem docelowym, a prawidłowy kontekst pliku nie jest określony w sepolicy specyficznej dla urządzenia, ten katalog nakładkowy dostawcy nie zostanie nałożony na katalog docelowy.

Aby użyć nakładki dostawcy, jądro musi włączyć OverlayFS poprzez ustawienie CONFIG_OVERLAY_FS=y . Ponadto jądro musi zostać połączone ze wspólnym jądrem 4.4 lub nowszym lub załatane za pomocą "overlayfs: override_creds=off option bypass creator_cred" .

Przykład wdrożenia nakładki dostawcy

Ta procedura demonstruje implementację nakładki dostawcy, która nakłada się na katalogi /vendor/lib/* , /vendor/etc/* i /vendor/app/* .

  1. Dodaj gotowe pliki dostawców do device/<vendor>/<target>/vendor_overlay/<target_vendor_version>/ :

    device/google/device/vendor_overlay/28/lib/libfoo.so
    device/google/device/vendor_overlay/28/lib/libbar.so
    device/google/device/vendor_overlay/28/etc/baz.xml
    device/google/device/vendor_overlay/28/app/qux.apk
    
  2. Zainstaluj gotowe pliki dostawcy w katalogu product/vendor_overlay w device/google/device/device.mk :

    PRODUCT_COPY_FILES += \
        $(call find-copy-subdir-files,*,device/google/device/vendor_overlay,$(TARGET_COPY_OUT_PRODUCT)/vendor_overlay)
    
  3. Zdefiniuj konteksty plików, jeśli docelowe pliki partycji vendor mają konteksty inne niż vendor_file . Ponieważ /vendor/lib/* używa kontekstu vendor_file , ten przykład nie obejmuje tego katalogu.

    Dodaj następujące polecenie do device/google/device-sepolicy/private/file_contexts :

    /(product|system/product)/vendor_overlay/[0-9]+/etc(/.*)?   u:object_r:vendor_configs_file:s0
    /(product|system/product)/vendor_overlay/[0-9]+/app(/.*)?   u:object_r:vendor_app_file:s0
    
  4. Zezwól procesowi init na zamontowanie nakładki dostawcy w kontekstach plików innych niż vendor_file . Ponieważ proces init ma już uprawnienia do montowania w kontekście vendor_file , w tym przykładzie nie zdefiniowano zasad dla vendor_file .

    Dodaj następujące polecenie do device/google/device-sepolicy/public/init.te :

    allow init vendor_configs_file:dir mounton;
    allow init vendor_app_file:dir mounton;
    

Sprawdzanie nakładki dostawcy

Aby sprawdzić konfigurację nakładki dostawcy, dodaj pliki w /product/vendor_overlay/<target_vendor_version>/<overlay_dir> i sprawdź, czy pliki są nakładane na pliki w /vendor/<overlay_dir> .

W przypadku kompilacji userdebug dostępny jest moduł testowy dla Atest :

$ atest -v fs_mgr_vendor_overlay_test

Aktualizacja do systemu jako root

Aby zaktualizować urządzenia inne niż A/B tak, aby korzystały z systemu jako root, należy zaktualizować schemat partycjonowania dla boot.img i system.img , skonfigurować dm-verity i usunąć wszelkie zależności rozruchowe z folderów głównych specyficznych dla urządzenia.

Aktualizowanie partycji

W przeciwieństwie do urządzeń A/B, które zmieniają przeznaczenie /boot jako partycji odzyskiwania , urządzenia inne niż A/B muszą oddzielać partycję /recovery , ponieważ nie mają rezerwowej partycji gniazda (na przykład od boot_a do boot_b ). Jeśli /recovery zostanie usunięta na urządzeniu innym niż A/B i upodobniona do schematu A/B, tryb odzyskiwania może zostać uszkodzony w przypadku nieudanej aktualizacji partycji /boot . Z tego powodu partycja /recovery musi być oddzielną partycją od /boot w przypadku urządzeń innych niż A/B, co oznacza, że ​​obraz odzyskiwania będzie nadal aktualizowany z opóźnieniem (to znaczy tak samo jak na urządzeniach z systemem Android 8.1.0 lub niższa).

W poniższej tabeli wymieniono różnice w partycjach obrazu dla urządzeń innych niż A/B przed i po systemie Android 9.

Obraz Ramdysk (przed 9) System jako root (po 9)
boot.img Zawiera jądro i plik ramdisk.img :
ramdisk.img
  -/
    - init.rc
    - init
    - etc -> /system/etc
    - system/ (mount point)
    - vendor/ (mount point)
    - odm/ (mount point)
    ...
Zawiera tylko normalne jądro rozruchowe.
recovery.img Zawiera jądro odzyskiwania i plik ramdisk.img odzyskiwania.
system.img Zawiera następujące elementy:
system.img
  -/
    - bin/
    - etc
    - vendor -> /vendor
    - ...
Zawiera połączoną zawartość oryginalnych plików system.img i ramdisk.img :
system.img
  -/
    - init.rc
    - init
    - etc -> /system/etc
    - system/
      - bin/
      - etc/
      - vendor -> /vendor
      - ...
    - vendor/ (mount point)
    - odm/ (mount point)
    ...

Same partycje nie ulegają zmianie; zarówno ramdysk, jak i system jako root używają następującego schematu partycji:

  • /boot
  • /system
  • /system
  • /recovery
  • /vendor itp.

Konfigurowanie dm-verity

W systemie jako root jądro musi zamontować system.img w / (punkt montowania) z dm-verity . AOSP obsługuje następujące implementacje dm-verity dla system.img .

vboot 1.0

W przypadku vboot 1.0 jądro musi przeanalizować metadane specyficzne dla Androida w /system , a następnie przekonwertować je na parametry dm-verity , aby skonfigurować dm-verity (wymaga tych poprawek jądra ). Poniższy przykład pokazuje ustawienia związane z dm-verity dla systemu jako root w wierszu poleceń jądra:

ro root=/dev/dm-0 rootwait skip_initramfs init=/init
dm="system none ro,0 1 android-verity /dev/sda34"
veritykeyid=id:7e4333f9bba00adfe0ede979e28ed1920492b40f

vboot 2.0

W przypadku vboot 2.0 ( AVB ) program ładujący musi zintegrować external/avb/libavb , który następnie analizuje deskryptor hashtree dla /system , konwertuje go na parametry dm-verity i na koniec przekazuje parametry do jądra za pomocą wiersza poleceń jądra. (Deskryptory Hashtree /system mogą znajdować się w /vbmeta lub w samym /system .)

vboot 2.0 wymaga następujących poprawek jądra:

Poniższy przykład pokazuje ustawienia związane z dm-verity dla systemu jako root w wierszu poleceń jądra:

ro root=/dev/dm-0 rootwait  skip_initramfs init=/init

dm="1 vroot none ro 1,0 5159992 verity 1
PARTUUID=00000016-0000-0000-0000-000000000000
PARTUUID=00000016-0000-0000-0000-000000000000 4096 4096 644999 644999
sha1 d80b4a8be3b58a8ab86fad1b498640892d4843a2
8d08feed2f55c418fb63447fec0d32b1b107e42c 10 restart_on_corruption
ignore_zero_blocks use_fec_from_device
PARTUUID=00000016-0000-0000-0000-000000000000 fec_roots 2 fec_blocks
650080 fec_start 650080"

Korzystanie z folderów głównych specyficznych dla urządzenia

W przypadku systemu jako root, po sflashowaniu ogólnego obrazu systemu (GSI) na urządzeniu (i przed uruchomieniem testów pakietu Vendor Test Suite ), wszelkie foldery główne specyficzne dla urządzenia dodane za pomocą BOARD_ROOT_EXTRA_FOLDERS znikają, ponieważ cała zawartość katalogu głównego została zastąpiona przez GSI systemu jako root. Usunięcie tych folderów może spowodować, że urządzenie stanie się niemożliwe do uruchomienia, jeśli istnieje zależność od folderów głównych specyficznych dla urządzenia (na przykład są one używane jako punkty montowania).

Aby uniknąć tego problemu, nie używaj BOARD_ROOT_EXTRA_FOLDERS do dodawania folderów głównych specyficznych dla urządzenia. Jeśli chcesz określić punkty montowania specyficzne dla urządzenia, użyj /mnt/vendor/<mount point> (dodano w tych listach zmian ). Te specyficzne dla dostawcy punkty montowania można bezpośrednio określić zarówno w drzewie urządzeń fstab (dla pierwszego etapu montowania), jak i w pliku /vendor/etc/fstab.{ro.hardware} bez dodatkowej konfiguracji (ponieważ fs_mgr tworzy je w /mnt/vendor/* automatycznie).