W Androidzie 10 główny system plików nie jest już uwzględniany w ramdisk.img, ale jest scalany z system.img (czyli system.img jest zawsze tworzony tak, jakby ustawiona była wartość BOARD_BUILD_SYSTEM_ROOT_IMAGE). Urządzenia wprowadzone na rynek z Androidem 10:
- Używaj układu partycji systemowej jako głównej (jest on automatycznie wymuszany przez kompilację bez opcji zmiany tego zachowania).
- Musi używać dysku RAM, który jest wymagany w przypadku dm-linear.
- Musisz ustawić wartość
BOARD_BUILD_SYSTEM_ROOT_IMAGEnafalse. To ustawienie służy tylko do rozróżniania urządzeń, które używają dysku RAM, od urządzeń, które go nie używają (i zamiast tego montująsystem.imgbezpośrednio).
Znaczenie konfiguracji system-as-root różni się w zależności od tego, czy jest to Android 9 czy Android 10. W konfiguracji systemu Android 9 z systemem jako katalogiem głównym wartość BOARD_BUILD_SYSTEM_ROOT_IMAGE jest ustawiona na true, co wymusza scalenie systemu plików root z system.img, a następnie zamontowanie system.img jako systemu plików root (rootfs). Ta konfiguracja jest obowiązkowa w przypadku urządzeń z Androidem 9, ale opcjonalna w przypadku urządzeń, które są aktualizowane do Androida 9, oraz urządzeń z Androidem w starszej wersji. W konfiguracji systemu Android 10 jako katalogu głównego kompilacja zawsze łączy $TARGET_SYSTEM_OUT i $TARGET_ROOT_OUT w system.img. Ta konfiguracja jest domyślnym działaniem na wszystkich urządzeniach z Androidem 10.
Android 10 wprowadza dalsze zmiany, aby obsługiwać dynamiczne partycje, system partycjonowania przestrzeni użytkownika, który umożliwia aktualizacje bezprzewodowe (OTA) w celu tworzenia, zmiany rozmiaru lub usuwania partycji. W ramach tej zmiany jądro Linuksa nie może już montować logicznej partycji systemowej na urządzeniach z Androidem 10, więc ta operacja jest obsługiwana przez pierwszy etap inicjowania.
W kolejnych sekcjach opisano wymagania dotyczące systemu jako katalogu głównego w przypadku aktualizacji OTA tylko systemu, a także podano wskazówki dotyczące aktualizowania urządzeń w celu korzystania z systemu jako katalogu głównego (w tym zmiany układu partycji i wymagania dotyczące jądra dm-verity). Szczegółowe informacje o zmianach w ramdysku znajdziesz w sekcji Partycje ramdysku.
Informacje o aktualizacjach OTA tylko systemu
Aktualizacje OTA tylko systemu, które umożliwiają aktualizowanie wersji Androida system.img i product.img bez zmiany innych partycji, wymagają układu partycji system-as-root. Wszystkie urządzenia z Androidem 10 muszą korzystać z układu partycji system-as-root, aby umożliwić aktualizacje OTA tylko systemu.
- Urządzenia A/B, które montują partycję
systemjako rootfs, korzystają już z systemu jako katalogu głównego i nie wymagają zmian, aby obsługiwać aktualizacje OTA systemu. - Urządzenia inne niż A/B, które montują partycję
systemw/system, muszą zostać zaktualizowane, aby korzystać z układu partycji system-as-root i obsługiwać aktualizacje OTA systemu.
Szczegółowe informacje o urządzeniach A/B i innych znajdziesz w artykule Aktualizacje systemu A/B (bezproblemowe).
Używanie nakładki dostawcy (≤ AOSP 14)
Nakładka dostawcy umożliwia nakładanie zmian na vendor
partycję podczas uruchamiania urządzenia. Nakładka dostawcy to zestaw modułów dostawcy w product, które są nakładane na vendor podczas uruchamiania urządzenia, zastępując i dodając istniejące moduły.
Po uruchomieniu urządzenia proces init kończy montowanie pierwszego etapu i odczytuje właściwości domyślne. Następnie wyszukuje
/product/vendor_overlay/<target_vendor_version> i montuje
każdy podkatalog w odpowiednim katalogu partycji vendor,
jeśli spełnione są te warunki:
/vendor/<overlay_dir>istnieje./product/vendor_overlay/<target_vendor_version>/<overlay_dir>ma taki sam kontekst pliku jak/vendor/<overlay_dir>.initma uprawnienia do montowania w kontekście pliku/vendor/<overlay_dir>.
Wdrażanie nakładki dostawcy
Zainstaluj pliki nakładki dostawcy w /product/vendor_overlay/<target_vendor_version>. Te pliki nakładają się na partycję vendor podczas uruchamiania urządzenia, zastępując pliki o tej samej nazwie i dodając nowe pliki. Nakładka dostawcy nie może usuwać plików z partycji vendor.
Pliki nakładek dostawcy muszą mieć taki sam kontekst pliku jak pliki docelowe, które zastępują w partycji vendor. Domyślnie pliki w katalogu /product/vendor_overlay/<target_vendor_version> mają kontekst vendor_file. Jeśli wystąpią niezgodności kontekstu plików między plikami nakładki dostawcy a plikami, które zastępują, określ to w zasadach bezpieczeństwa specyficznych dla urządzenia. Kontekst pliku jest ustawiany na poziomie katalogu. Jeśli kontekst pliku katalogu nakładki dostawcy nie pasuje do katalogu docelowego, a w zasadach sepolicy dotyczących urządzenia nie określono prawidłowego kontekstu pliku, katalog nakładki dostawcy nie zostanie nałożony na katalog docelowy.
Aby korzystać z nakładki dostawcy, jądro musi włączyć OverlayFS, ustawiając CONFIG_OVERLAY_FS=y. Jądro musi być też scalone z wspólnym jądrem w wersji 4.4 lub nowszej albo poprawione za pomocą "overlayfs:
override_creds=off option bypass creator_cred".
Przykład implementacji nakładki dostawcy
W tej procedurze pokazujemy, jak wdrożyć nakładkę dostawcy, która nakłada się na katalogi /vendor/lib/*, /vendor/etc/* i /vendor/app/*.
-
Dodawanie gotowych plików dostawców w
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
-
Zainstaluj gotowe pliki dostawcy w folderze
product/vendor_overlayw folderzedevice/google/device/device.mk:PRODUCT_COPY_FILES += \ $(call find-copy-subdir-files,*,device/google/device/vendor_overlay,$(TARGET_COPY_OUT_PRODUCT)/vendor_overlay)
-
Zdefiniuj konteksty plików, jeśli docelowe
vendorpliki partycji mają konteksty inne niżvendor_file. Ponieważ/vendor/lib/*używa kontekstuvendor_file, w tym przykładzie nie ma tego katalogu.Dodaj te elementy do pliku
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
-
Zezwól procesowi
initna montowanie nakładki dostawcy w kontekstach plików innych niżvendor_file. Ponieważinitproces ma już uprawnienia do montowania w kontekścievendor_file, w tym przykładzie nie zdefiniowano zasad dlavendor_file.Dodaj te elementy do pliku
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ć poprawność konfiguracji 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 Atest:
$ atest -v fs_mgr_vendor_overlay_test
Aktualizacja do systemu jako katalogu głównego
Aby zaktualizować urządzenia inne niż A/B i umożliwić im korzystanie z systemu jako katalogu głównego, musisz zaktualizować schemat partycjonowania dla boot.img i system.img, skonfigurować dm-verity i usunąć wszelkie zależności rozruchowe od folderów głównych specyficznych dla urządzenia.
Aktualizowanie partycji
W przeciwieństwie do urządzeń A/B, które wykorzystują /boot jako partycję przywracania, urządzenia inne niż A/B muszą zachować oddzielną partycję /recovery, ponieważ nie mają partycji gniazda rezerwowego (np. z boot_a do boot_b). Jeśli na urządzeniu innym niż A/B usuniesz partycję /recovery i sprawisz, że będzie podobna do schematu A/B, tryb przywracania może przestać działać podczas nieudanej aktualizacji partycji /boot. Z tego powodu partycja /recovery musi być oddzielną partycją od /boot na urządzeniach bez systemu A/B, co oznacza, że obraz przywracania systemu jest nadal aktualizowany w sposób odroczony (czyli tak samo jak na urządzeniach z Androidem 8.1.0 lub starszym).
W tabeli poniżej znajdziesz różnice w podziale obrazu na partycje na urządzeniach bez podziału A/B przed Androidem 9 i po nim.
| Obraz | Ramdysk (przed Androidem 9) | System jako katalog główny (po Androidzie 9) |
|---|---|---|
boot.img |
Zawiera jądro i 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 obraz odzyskiwaniaramdisk.img. |
|
system.img |
Zawiera te elementy:
system.img
-/
- bin/
- etc
- vendor -> /vendor
- ... |
Zawiera połączone treści z 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-as-root korzystają z tego samego schematu partycji:
/boot/system/system/recovery/vendoritp.
Konfigurowanie dm-verity
W przypadku systemu jako katalogu głównego jądro musi podłączyć system.img w / (punkt podłączania) za pomocą dm-verity. AOSP obsługuje te implementacje dm-verity
w przypadku system.img.
vboot 1.0
W przypadku vboot 1.0 jądro musi przeanalizować metadane specyficzne dla Androida na /system, a następnie przekonwertować je na parametry dm-verity, aby skonfigurować dm-verity (wymaga to tych poprawek jądra).
W przykładzie poniżej pokazujemy ustawienia związane z dm-verity dla systemu jako katalogu głównego 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 rozruchowy musi zintegrować external/avb/libavb, który następnie analizuje deskryptor drzewa skrótów dla /system, przekształca go w parametry dm-verity i przekazuje je do jądra za pomocą wiersza poleceń jądra. (Deskryptory drzewa skrótów /system mogą znajdować się w /vbmeta lub w /system).
vboot 2.0 wymaga tych poprawek jądra:
- https://android-review.googlesource.com/#/c/kernel/common/+/158491/
- kernel 4.4 patches,kernel 4.9 patches itp.
W przykładzie poniżej pokazujemy ustawienia związane z dm-verity dla systemu jako katalogu głównego 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"
Używanie folderów głównych przeznaczonych na konkretne urządzenia
W przypadku systemu z partycją systemową jako katalogiem głównym po wgraniu na urządzenie podstawowego obrazu systemu (GSI) (i przed uruchomieniem testów Vendor Test Suite) wszystkie 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 z partycją systemową jako katalogiem głównym. Usunięcie tych folderów może spowodować, że urządzenie nie będzie się uruchamiać, jeśli istnieje zależność od folderów głównych specyficznych dla urządzenia (np. 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 musisz określić punkty montowania specyficzne dla urządzenia, użyj /mnt/vendor/<mount point> (dodano w tych listach zmian). Te punkty montowania specyficzne dla dostawcy można określić bezpośrednio w drzewie urządzenia fstab (w przypadku montowania na pierwszym etapie) i w pliku /vendor/etc/fstab.{ro.hardware} bez dodatkowej konfiguracji (ponieważ fs_mgr tworzy je automatycznie w folderze /mnt/vendor/*).