Format kontenera Android Pony EXpress (APEX) został wprowadzony na Androida. 10 i jest używany podczas instalacji w systemach niższego poziomu. modułów. Ten format ułatwia aktualizację komponentów systemu, które nie pasują do siebie do standardowego modelu aplikacji na Androida. Niektóre przykładowe komponenty są natywne usługi i biblioteki, warstwy abstrakcji sprzętu (HAL), czas działania (ART) i biblioteki klas.
Termin „APEX” może też odnosić się do pliku APEX.
Tło
Android obsługuje aktualizacje modułów, które pasują do standardowej aplikacji. (np. usługi czy aktywności) za pomocą aplikacji instalatora pakietów (np. aplikacji Sklep Google Play) przy użyciu podobnego modelu w przypadku komponentów systemu operacyjnego niższego poziomu ma następujące wady:
- Modułów opartych na pliku APK nie można używać na wczesnym etapie sekwencji rozruchu. Przesyłka Menedżer to główne repozytorium informacji o aplikacjach. rozpoczyna się w menedżerze aktywności, który jest gotowy na późniejszym etapie i procedurę uruchamiania.
- Format APK (zwłaszcza plik manifestu) jest przeznaczony dla aplikacji na Androida i moduły systemowe nie zawsze są dobrze dopasowane.
Projektowanie
W tej sekcji znajdziesz ogólny opis formatu pliku APEX oraz Menedżer APEX – usługa zarządzająca plikami APEX.
Więcej informacji na temat tego, dlaczego wybrany został ten sposób wyświetlania w przypadku APEX, znajdziesz w Alternatywy brane pod uwagę przy rozwijaniu APEX.
Format APEX
Jest to format pliku APEX.
Rysunek 1. Format pliku APEX
Najwyższego poziomu plik APEX to plik ZIP, w którym przechowywane są pliki. nieskompresowany i znajdujący się na granicach 4 KB.
Plik APEX zawiera te 4 pliki:
apex_manifest.json
AndroidManifest.xml
apex_payload.img
apex_pubkey
Plik apex_manifest.json
zawiera nazwę i wersję pakietu, które
identyfikować pliki APEX. To jest
ApexManifest
bufor protokołu w formacie JSON.
Plik AndroidManifest.xml
zezwala pliku APEX na korzystanie z narzędzi związanych z pakietem APK
taką jak ADB, PackageManager oraz aplikacje instalatora pakietów (takie jak
Sklep Play). Na przykład plik APEX może korzystać z dotychczasowego narzędzia, takiego jak aapt
skontrolowanie podstawowych metadanych z pliku. Plik zawiera nazwę pakietu i
w informacjach o wersji. Te informacje są zwykle dostępne również w
apex_manifest.json
Aby uzyskać nowy kod, zalecana cena apex_manifest.json
to więcej niż AndroidManifest.xml
które obsługują APEX. AndroidManifest.xml
może zawierać dodatkowe
informacji na temat kierowania, które mogą być wykorzystywane przez istniejące narzędzia do publikowania aplikacji.
apex_payload.img
to obraz systemu plików ext4 korzystający z dm-verity. Obraz
jest podłączana w czasie działania za pomocą urządzenia w pętli. Drzewo haszu i
Bloki metadanych tworzy się za pomocą biblioteki libavb
. Ładunek systemu plików
nie jest przeanalizowany (ponieważ obraz powinien być możliwy do zamontowania). Zwykłe pliki są
zawarte w pliku apex_payload.img
.
apex_pubkey
to klucz publiczny używany do podpisywania obrazu systemu plików. W czasie działania
ten klucz gwarantuje, że pobrany APEX jest podpisany tym samym elementem
który podpisuje ten sam wskaźnik APEX
we wbudowanych partycjach.
Wytyczne dotyczące nazewnictwa APEX
Aby zapobiec konfliktom z nazwami nowych APEX w miarę rozwoju platformy, użyj tych wytycznych dotyczących nazewnictwa:
com.android.*
- Rezerwowany dla AOSP APEX. Nie jest unikalne dla żadnej firmy ani na żadnym urządzeniu.
com.<companyname>.*
- Zarezerwowane dla firmy. może być używany przez wiele urządzeń z tego kraju, firmy.
com.<companyname>.<devicename>.*
- Zarezerwowana dla punktów APEX, które są unikalne dla określonego urządzenia (lub podzbioru urządzeń).
Menedżer APEX
Menedżer APEX (apexd
) to samodzielny proces natywny odpowiedzialny za:
weryfikacji, instalowania i odinstalowywania plików APEX. Proces ten rozpoczyna się,
jest gotowa na wczesnym etapie sekwencji uruchamiania. Pliki APEX są zazwyczaj instalowane fabrycznie
urządzenia w grupie /system/apex
. Menedżer APEX domyślnie używa tych
w przypadku braku aktualizacji.
W sekwencji aktualizacji punktu APEX jest używany parametr Klasa PackageManager i występuje jak niżej.
- Plik APEX jest pobierany przez aplikację instalatora pakietów, ADB lub inne źródła.
- Menedżer pakietów rozpocznie procedurę instalacji. Gdy zauważyłem, że jest to APEX, menedżer pakietów przekazuje kontrolę do APEX .
- Menedżer APEX weryfikuje plik APEX.
- Jeśli plik APEX jest zweryfikowany, wewnętrzna baza danych menedżera APEX to jest zaktualizowany, tak aby odzwierciedlało, że plik APEX jest aktywowany przy następnym uruchomieniu.
- Żądanie instalacji otrzymuje komunikat po pomyślnym pakiecie weryfikacji.
- Aby kontynuować instalację, należy ponownie uruchomić system.
Przy następnym uruchomieniu menedżer APEX uruchamia się, odczytuje wewnętrzną bazę danych i wykona następujące elementy dla każdego wymienionego pliku APEX:
- Sprawdza plik APEX.
- Tworzy urządzenie pętli z pliku APEX.
- Tworzy urządzenie blokowe twórcy mapowania urządzeń na urządzeniu zapętlającym.
- Mocuje blokowe urządzenie mapera urządzeń w unikalnej ścieżce (na przykład
/apex/name@ver
).
Po podłączeniu wszystkich plików APEX wymienionych w wewnętrznej bazie danych interfejs APEX udostępnia usługę powiązania, która pozwala na wykonywanie zapytań dotyczących innych komponentów systemu o zainstalowanych plikach APEX. Na przykład drugi system może wysyłać zapytania o listę plików APEX zainstalowanych na urządzeniu lub wysyłać zapytania do dokładną ścieżkę, do której jest podłączony określony punkt APEX, tak by można było uzyskać dostęp do plików.
Pliki APEX to pliki APK
Pliki APEX są prawidłowymi plikami APK, ponieważ są to podpisane archiwa ZIP (z zastosowaniem
schematu podpisu APK) zawierający plik AndroidManifest.xml
. Dzięki temu APEX
z plikami do korzystania z infrastruktury plików APK, np. instalatorem pakietów
narzędzia do podpisywania i menedżera pakietów.
Plik AndroidManifest.xml
w pliku APEX jest ograniczony i składa się z elementów
pakiet name
, versionCode
i opcjonalnie targetSdkVersion
, minSdkVersion
,
i maxSdkVersion
w przypadku szczegółowego kierowania. Dzięki tej informacji APEX
za pomocą istniejących kanałów, takich jak aplikacje instalacyjne pakietów
ADB.
Obsługiwane typy plików
Format APEX obsługuje następujące typy plików:
- Natywne udostępniane biblioteki
- Natywne pliki wykonywalne
- Pliki JAR
- Pliki danych
- Pliki konfiguracyjne
Nie oznacza to, że APEX może aktualizować wszystkie te typy plików. Określa, czy plik że można aktualizować typ w zależności od platformy i tego, jak stabilne są definicje i interfejsy dla różnych typów plików.
Opcje podpisywania
Pliki APEX są logowane na 2 sposoby. Po pierwsze, apex_payload.img
(a konkretnie
plik deskryptor vbmeta dołączony do pliku apex_payload.img
) jest podpisany kluczem.
Następnie cały APEX jest podpisany za pomocą
Schemat podpisu pliku APK w wersji 3 Używane są 2 różne klucze
w tym procesie.
Po stronie urządzenia klucz publiczny odpowiadający kluczowi prywatnemu służącemu do podpisywania. deskryptor vbmeta jest zainstalowany. Menedżer APEX używa klucza publicznego do weryfikować punkty dostępu APEX, które mają zostać zainstalowane. Każdy APEX musi być podpisany za pomocą różnych kluczy i jest egzekwowane zarówno w czasie kompilacji, jak i w czasie działania.
APEX we wbudowanych partycjach
Pliki APEX mogą znajdować się we wbudowanych partycjach, np. /system
.
partycja jest już ponad dm-verity, więc pliki APEX są podłączane bezpośrednio
nad urządzeniem typu loopback.
Jeśli we wbudowanej partycji znajduje się APEX, można go zaktualizować przez
dostarcza pakiet APEX o tej samej nazwie pakietu i większej lub równej
do kodu wersji. Nowy raport APEX jest przechowywany w /data
i – podobnie jak w przypadku plików APK –
Nowo zainstalowana wersja zastępuje wersję już istniejącą
partycji danych. W przeciwieństwie do plików APK nowo zainstalowana wersja APEX jest dostępna
aktywowany po ponownym uruchomieniu.
Wymagania jądra systemu
Aby obsługiwać moduły APEX mainline na urządzeniu z Androidem, wymagane są funkcje jądra: sterownik pętli zwrotnej i dm-verity. Zapętlanie sterownik podłącza obraz systemu plików w module APEX, a dm-verity weryfikuje z modułu APEX.
Wydajność sterownika pętli i dm-weryfikacji ma duże znaczenie dla osiągnięcia dobrą wydajność systemu w przypadku modułów APEX.
Obsługiwane wersje jądra
Moduły APEX mainline są obsługiwane na urządzeniach z jądrem w wersji 4.4 lub wyższe. nowych urządzeniach z Androidem 10 lub nowszym; musi używać jądra w wersji 4.9 lub nowszej do obsługi modułów APEX.
Wymagane poprawki jądra systemu
Wymagane poprawki jądra obsługujących moduły APEX znajdują się w Popularne drzewo Androida. Aby pobrać poprawki do obsługi APEX, użyj najnowszej wersji systemu Android.
Jądro w wersji 4.4
Ta wersja jest obsługiwana tylko na urządzeniach, które zostały uaktualnione z Androida 9 do
Androida 10 i chcesz obsługiwać moduły APEX. Aby uzyskać
poprawek, scalanie w dół z gałęzi android-4.4
jest silnie
zalecane. Oto lista wymaganych pojedynczych poprawek
dla jądra w wersji 4.4.
- UPSTREAM: pętla: dodaj ioctl, by zmienić rozmiar bloku logicznego (4,4)
- BACKPORT: block/loop: ustaw hw_sectors (4,4)
- UPSTREAM: pętla: dodaj LOOP_SET_BLOCK_SIZE w zgodnym ioctl (4,4)
- ANDROID: mnt: Napraw next_descendent (4,4)
- ANDROID: mnt: remount powinna rozpowszechnić się wśród niewolników (4,4)
- ANDROID: mnt: poprawnie przeprowadź ponowną instalację (4,4)
- Przywróć „ANDROID: dm verity: dodaj minimalny rozmiar pobierania z wyprzedzeniem” (4,4)
- UPSTREAM: pętla: upuszczanie pamięci podręcznych w przypadku zmiany przesunięcia lub rozmiaru block_size (4,4)
Jądro w wersjach 4.9/4.14/4.19
Aby uzyskać wymagane poprawki do jądra w wersji 4.9/4.14/4.19, scal z
gałąź android-common
.
Wymagane opcje konfiguracji jądra
Na liście poniżej znajdziesz podstawowe wymagania konfiguracyjne w przypadku Moduły APEX wprowadzone w Androidzie 10. Elementy oznaczone gwiazdką (*) są dotychczasowe wymagania Androida w wersji 9 i starszych.
(*) CONFIG_AIO=Y # AIO support (for direct I/O on loop devices)
CONFIG_BLK_DEV_LOOP=Y # for loop device support
CONFIG_BLK_DEV_LOOP_MIN_COUNT=16 # pre-create 16 loop devices
(*) CONFIG_CRYPTO_SHA1=Y # SHA1 hash for DM-verity
(*) CONFIG_CRYPTO_SHA256=Y # SHA256 hash for DM-verity
CONFIG_DM_VERITY=Y # DM-verity support
Wymagania dotyczące parametrów wiersza poleceń jądra
Aby obsługiwać APEX, upewnij się, że parametry wiersza poleceń jądra spełniają te wymagania wymagania:
- Pole
loop.max_loop
NIE może być ustawione - Wartość
loop.max_part
musi być mniejsza niż 8
Zyskaj APEX
Z tej sekcji dowiesz się, jak utworzyć APEX za pomocą systemu kompilacji Androida.
Poniżej znajdziesz przykład użycia funkcji Android.bp
w przypadku obszaru APEX o nazwie apex.test
.
apex {
name: "apex.test",
manifest: "apex_manifest.json",
file_contexts: "file_contexts",
// libc.so and libcutils.so are included in the apex
native_shared_libs: ["libc", "libcutils"],
binaries: ["vold"],
java_libs: ["core-all"],
prebuilts: ["my_prebuilt"],
compile_multilib: "both",
key: "apex.test.key",
certificate: "platform",
}
Przykład strony apex_manifest.json
:
{
"name": "com.android.example.apex",
"version": 1
}
Przykład strony file_contexts
:
(/.*)? u:object_r:system_file:s0
/sub(/.*)? u:object_r:sub_file:s0
/sub/file3 u:object_r:file3_file:s0
Typy i lokalizacje plików w APEX
Typ pliku | Lokalizacja w APEX |
---|---|
Biblioteki udostępnione | /lib i /lib64 (/lib/arm dla
przetłumaczona ramię w x86) |
Pliki wykonywalne | /bin |
Biblioteki Java | /javalib |
Gotowe | /etc |
Zależności pośrednie
Pliki APEX automatycznie uwzględniają przechodnie zależności natywnych współdzielonych bibliotek
lub wykonywalne. Jeśli na przykład libFoo
zależy od libBar
, te 2 lib to:
jest uwzględniane, gdy we właściwości native_shared_libs
występuje tylko wartość libFoo
.
Obsługa kilku interfejsów ABI
Zainstaluj właściwość native_shared_libs
zarówno dla zasobu głównego, jak i dodatkowego
interfejsów binarnych aplikacji (ABI) urządzenia. Jeśli segment APEX jest kierowany na urządzenia
z pojedynczym interfejsem ABI (czyli tylko 32- lub 64-bitowym) tylko biblioteki z
zainstalowany jest odpowiedni interfejs ABI.
Zainstaluj właściwość binaries
tylko dla głównego interfejsu ABI urządzenia jako
opisane poniżej:
- Jeśli urządzenie jest tylko 32-bitowe, Zainstalowano.
- Jeśli urządzenie ma tylko wersję 64-bitową, Zainstalowano.
Aby zapewnić szczegółową kontrolę nad interfejsami ABI bibliotek natywnych i plikami binarnymi,
użyj
multilib.[first|lib32|lib64|prefer32|both].[native_shared_libs|binaries]
usług.
first
: pasuje do głównego interfejsu ABI urządzenia. Jest to ustawienie domyślne dla pliki binarne.lib32
: pasuje do 32-bitowego interfejsu ABI urządzenia, jeśli jest obsługiwany.lib64
: pasuje do 64-bitowego interfejsu ABI urządzenia (obsługiwane).prefer32
: pasuje do 32-bitowego interfejsu ABI urządzenia, jeśli jest obsługiwany. Jeśli 32-bitowy ABI nie jest obsługiwany; pasuje do 64-bitowego interfejsu ABI.both
: pasuje do obu interfejsów ABI. Jest to ustawienie domyślne dlanative_shared_libraries
Właściwości java
, libraries
i prebuilts
są niezależne od interfejsu ABI.
Ten przykład dotyczy urządzenia, które obsługuje tryb 32/64 i nie preferuje formatu 32:
apex {
// other properties are omitted
native_shared_libs: ["libFoo"], // installed for 32 and 64
binaries: ["exec1"], // installed for 64, but not for 32
multilib: {
first: {
native_shared_libs: ["libBar"], // installed for 64, but not for 32
binaries: ["exec2"], // same as binaries without multilib.first
},
both: {
native_shared_libs: ["libBaz"], // same as native_shared_libs without multilib
binaries: ["exec3"], // installed for 32 and 64
},
prefer32: {
native_shared_libs: ["libX"], // installed for 32, but not for 64
},
lib64: {
native_shared_libs: ["libY"], // installed for 64, but not for 32
},
},
}
podpisywanie vbmeta
Podpisz każdy APEX innymi kluczami. Gdy wymagany jest nowy klucz, utwórz
i utworzyć moduł apex_key
. Używaj właściwości key
do:
podpisz APEX za pomocą tego klucza. Klucz publiczny jest automatycznie dodawany do
APEX o nazwie avb_pubkey
.
# create an rsa key pairopenssl genrsa -out foo.pem 4096
# extract the public key from the key pairavbtool extract_public_key --key foo.pem --output foo.avbpubkey
# in Android.bpapex_key { name: "apex.test.key", public_key: "foo.avbpubkey", private_key: "foo.pem", }
W powyższym przykładzie nazwa klucza publicznego (foo
) staje się identyfikatorem klucza
. Identyfikator klucza używanego do podpisania raportu APEX jest zapisywany w APEX. W czasie działania
apexd
weryfikuje APEX za pomocą klucza publicznego z tym samym identyfikatorem na urządzeniu.
Podpisywanie APEX
Podpisuj APEX w taki sam sposób, w jaki podpisujesz pliki APK. Dwukrotnie podpisz APEX. raz dla
minisystemie plików (apex_payload.img
plik) i jeden raz dla całego pliku.
Aby podpisać APEX na poziomie pliku, ustaw właściwość certificate
w jednym ze
te 3 sposoby:
- Nie ustawiono: jeśli nie jest ustawiona żadna wartość, punkt APEX jest podpisany za pomocą certyfikatu znajdującego się
o
PRODUCT_DEFAULT_DEV_CERTIFICATE
. Jeśli nie zostanie ustawiona żadna flaga, domyślna ścieżka dobuild/target/product/security/testkey
. <name>
: APEX jest podpisany certyfikatem<name>
w tym samym katalogu jakoPRODUCT_DEFAULT_DEV_CERTIFICATE
.:<name>
: APEX jest podpisany certyfikatem zdefiniowanym przez Moduł utworu o nazwie<name>
. Moduł certyfikatu można zdefiniować jako co dalej.
android_app_certificate {
name: "my_key_name",
certificate: "dir/cert",
// this will use dir/cert.x509.pem (the cert) and dir/cert.pk8 (the private key)
}
Zainstaluj APEX
Aby zainstalować APEX, użyj ADB.
adb install apex_file_name
adb reboot
Jeśli supportsRebootlessUpdate
ma wartość true
w tabeli apex_manifest.json
, a parametry
obecnie zainstalowany APEX nie jest używany (na przykład zawarte w nim usługi mają
został zatrzymany), nowy APEX można zainstalować bez ponownego uruchamiania,
--force-non-staged
.
adb install --force-non-staged apex_file_name
Wykorzystaj APEX
Po ponownym uruchomieniu interfejs APEX jest podłączony w: /apex/<apex_name>@<version>
katalogu. Jednocześnie można podłączyć wiele wersji tego samego punktu APEX.
Spośród ścieżek podłączenia ta, która odpowiada najnowszej wersji, to
powiązane konto użytkownika o /apex/<apex_name>
.
Klienci mogą używać ścieżki podłączonej do powiązania do odczytu i wykonywania plików z APEX.
Wskaźniki APEX są zwykle używane w ten sposób:
- OEM lub ODM wstępnie wczytuje APEX poniżej
/system/apex
, gdy urządzenie wysłano. - Dostęp do plików w APEX uzyskuje się przez ścieżkę
/apex/<apex_name>/
. - Jeśli w
/data/apex
jest zainstalowana zaktualizowana wersja raportu APEX, ścieżka wskazuje nowy punkt APEX po ponownym uruchomieniu.
Aktualizowanie usługi przy użyciu numeru APEX
Aby zaktualizować usługę przy użyciu punktu dostępu APEX:
Oznacz usługę na partycji systemowej jako możliwą do aktualizacji. Dodaj opcję
updatable
do definicji usługi./system/etc/init/myservice.rc: service myservice /system/bin/myservice class core user system ... updatable
Utwórz nowy plik
.rc
dla zaktualizowanej usługi. Użyj opcjioverride
, aby ponownie zdefiniować istniejącą usługę./apex/my.apex/etc/init.rc: service myservice /apex/my.apex/bin/myservice class core user system ... override
Definicje usług można zdefiniować tylko w pliku .rc
APEX. Działanie
nie są obsługiwane w krajach/regionach docelowych.
Jeśli usługa oznaczona jako dostępna do aktualizacji uruchomi się przed aktywacją punktów APEX, makro rozpoczęcie jest opóźnione do czasu zakończenia aktywacji punktów APEX.
Skonfiguruj system do obsługi aktualizacji APEX
Ustaw właściwość systemową na true
, aby obsługiwać aktualizacje plików APEX.
<device.mk>:
PRODUCT_PROPERTY_OVERRIDES += ro.apex.updatable=true
BoardConfig.mk:
TARGET_FLATTEN_APEX := false
lub po prostu
<device.mk>:
$(call inherit-product, $(SRC_TARGET_DIR)/product/updatable_apex.mk)
Spłaszczony APEX
W przypadku starszych urządzeń zaktualizowanie starych danych jest czasem niemożliwe lub niemożliwe
ją jądro, aby w pełni obsługiwać APEX. Na przykład jądro zostało stworzone
bez narzędzia CONFIG_BLK_DEV_LOOP=Y
, co jest niezbędne do podłączenia systemu plików
wewnątrz obszaru APEX.
Spłaszczony APEX to specjalnie utworzony APEX, który można aktywować na urządzeniach
do starszego jądra systemu. Pliki w rozdzielonym APEX są instalowane bezpośrednio w katalogu
na wbudowanej partycji. Na przykład lib/libFoo.so
w rozdzielonym punkcie APEX
Aplikacja my.apex
została zainstalowana w: /system/apex/my.apex/lib/libFoo.so
.
Aktywowanie płaskiego punktu APEX nie obejmuje urządzenia z pętlą. Całość
katalog /system/apex/my.apex
jest bezpośrednio połączony z serwerem /apex/name@ver
.
Spłaszczonych punktów APEX nie można aktualizować, pobierając zaktualizowane wersje punktów APEX z sieci, ponieważ nie można ich rozdzielić. Rozdzielone punkty APEX można aktualizować tylko za pomocą zwykłego OTA.
Spłaszczony APEX to konfiguracja domyślna. Oznacza to, że wszystkie Punkty APEX są domyślnie rozdzielane, chyba że osobno skonfigurujesz urządzenie aby tworzyć niespłaszczone APEX na potrzeby ich aktualizacji (jak wyjaśniliśmy powyżej).
Łączenie w urządzeniu spłaszczonych i niespłaszczonych węzłów APEX NIE JEST
obsługiwane. Punkty APEX w urządzeniu muszą być albo niespłaszczone, albo w całości spłaszczone.
Jest to szczególnie ważne w przypadku dostawy wstępnie podpisanych baz APEX
takich jak Mainline. APEX, które nie są wstępnie podpisane (czyli utworzone na podstawie
źródła) powinny być też niespłaszczone i podpisane odpowiednimi kluczami.
urządzenie powinno dziedziczyć ustawienie updatable_apex.mk
, zgodnie z opisem w sekcji
Aktualizowanie usługi za pomocą punktu APEX.
Skompresowane APEX
Android 12 i nowsze używają kompresji APEX do zmniejszanie wpływu aktualizacji APEX na miejsce na dane. Po zaktualizowaniu do Rozszerzenie APEX jest zainstalowane, ale jego wstępnie zainstalowana wersja nie jest już używana, nadal zajmuje taką samą ilość miejsca. Zajmowane miejsce pozostaje niedostępne.
Kompresja APEX minimalizuje wpływ na pamięć masową dzięki zastosowaniu mocno skompresowanego zestawu
plików APEX na partycjach tylko do odczytu (takich jak partycja /system
). Android,
w wersji 12 i nowszych używają algorytmu kompresji ZIP DEFLATE.
Kompresja nie zapewnia optymalizacji:
Wczytywanie APEX, które muszą być zamontowane bardzo na wczesnym etapie uruchamiania kolejne wartości.
Nieaktualizowane węzły APEX. Kompresja jest korzystna tylko wtedy, gdy zainstalowana jest zaktualizowana wersja APEX na partycji
/data
. Pełna lista aktualnych APEX jest dostępna na Elementy systemu modułowego stronę.Dynamic shared libs APEX. Ponieważ
apexd
zawsze aktywuje obie wersje takich aplikacji APEX (wstępnie zainstalowanych i uaktualnionych), kompresowanie ich nie przynosi efektu.
Skompresowany format pliku APEX
Jest to format skompresowanego pliku APEX.
Rysunek 2. Skompresowany format pliku APEX
Na najwyższym poziomie skompresowany plik APEX to plik ZIP zawierający plik apex w formie z niedoprecyzowanym poziomem kompresji 9 oraz innymi plikami i nieskompresowane.
Cztery pliki składają się na plik APEX:
original_apex
: obniżona cena z poziomem kompresji 9 To jest oryginalny, nieskompresowany plik APEX.apex_manifest.pb
: tylko zapisaneAndroidManifest.xml
: tylko zapisaneapex_pubkey
: tylko zapisane
Pliki apex_manifest.pb
, AndroidManifest.xml
i apex_pubkey
są
kopii odpowiednich plików w usłudze original_apex
.
Utwórz skompresowany APEX
Skompresowany APEX można utworzyć za pomocą narzędzia apex_compression_tool.py
znajdującego się na stronie
system/apex/tools
W systemie kompilacji dostępnych jest kilka parametrów związanych z kompresją APEX.
W Android.bp
o tym, czy plik APEX można skompresować, steruje klucz
Właściwość compressible
:
apex {
name: "apex.test",
manifest: "apex_manifest.json",
file_contexts: "file_contexts",
compressible: true,
}
Flaga produktu PRODUCT_COMPRESSED_APEX
określa, czy obraz systemu został utworzony
ze źródła musi zawierać skompresowane pliki APEX.
W przypadku eksperymentów lokalnych możesz wymusić kompresję przez kompresję punktów APEX przez ustawienie
OVERRIDE_PRODUCT_COMPRESSED_APEX=
do true
.
Skompresowane pliki APEX wygenerowane przez system kompilacji mają rozszerzenie .capex
.
Rozszerzenie ułatwia rozróżnienie między skompresowanymi i nieskompresowanymi.
różnych wersji pliku APEX.
Obsługiwane algorytmy kompresji
Android 12 obsługuje tylko kompresję deflate-zip.
Aktywowanie skompresowanego pliku APEX podczas uruchamiania
Zanim będzie można aktywować skompresowany plik APEX, zawarty w nim plik original_apex
zdekompresowany do katalogu /data/apex/decompressed
. W wyniku
zdekompresowany plik APEX jest na stałe połączony z katalogiem /data/apex/active
.
Poniższy przykład ilustruje proces opisany powyżej.
Traktuj /system/apex/com.android.foo.capex
jako skompresowany obszar APEX
aktywowano z kodem wersji 37.
- Plik
original_apex
w lokalizacji/system/apex/com.android.foo.capex
to zdekompresowano do formatu/data/apex/decompressed/com.android.foo@37.apex
. restorecon /data/apex/decompressed/com.android.foo@37.apex
wykonuje się, aby Sprawdź, czy ma prawidłową etykietę SELinux.- Weryfikacja jest przeprowadzana
/data/apex/decompressed/com.android.foo@37.apex
, aby upewnić się, że są prawidłowe:apexd
sprawdza klucz publiczny w pakiecie/data/apex/decompressed/com.android.foo@37.apex
, aby sprawdzić, czy jest równa do aplikacji w pakiecie/system/apex/com.android.foo.capex
. - Plik
/data/apex/decompressed/com.android.foo@37.apex
jest na stałe połączony z: w katalogu/data/apex/active/com.android.foo@37.apex
. - Zwykła logika aktywacji nieskompresowanych plików APEX jest wykonywana
/data/apex/active/com.android.foo@37.apex
Interakcja z internetem OTA
Skompresowane pliki APEX mają wpływ na przesyłanie OTA i jego zastosowanie. Od aktualizacja OTA może zawierać skompresowany plik APEX w wersji wyższego poziomu. niż aktywna na urządzeniu, musi być zarezerwowana pewna ilość wolnego miejsca przed ponownym uruchomieniem urządzenia w celu zastosowania aktualizacji OTA.
Aby obsługiwać system OTA, apexd
udostępnia 2 interfejsy API powiązań:
calculateSizeForCompressedApex
– oblicza rozmiar wymagany do dekompresji APEX w pakiecie OTA. Może to służyć do sprawdzania, czy urządzenie musi wystarczyć miejsca na pobranie aktualizacji OTA.reserveSpaceForCompressedApex
– rezerwuje miejsce na dysku do wykorzystania w przyszłości. przezapexd
, by zdekompresować skompresowane pliki APEX w pakiecie OTA.
W przypadku aktualizacji A/B OTA apexd
podejmuje próbę dekompresji w interfejsie
w ramach procedury OTA po instalacji. Jeśli dekompresja się nie powiedzie,
apexd
wykonuje dekompresję podczas uruchamiania, aby zastosować OTA.
.
Alternatywy brane pod uwagę przy rozwijaniu APEX
Oto kilka opcji, które AOSP brał pod uwagę przy projektowaniu pliku APEX oraz powody ich uwzględnienia lub wykluczenia.
Zwykłe systemy zarządzania pakietami
Dystrybucje Linuksa mają systemy zarządzania pakietami, takie jak dpkg
i rpm
,
które mają moc,
i wytrzymałość. Nie byli to jednak
również dla APEX, ponieważ nie są w stanie chronić przesyłek
instalacji. Weryfikacja jest przeprowadzana tylko podczas instalowania pakietów.
Hakerzy mogą niezauważyć naruszenia integralności zainstalowanych pakietów. To jest
w przypadku Androida – wszystkie komponenty systemu były przechowywane w trybie tylko do odczytu
systemów plików, których integralność jest chroniona dm-verity podczas każdego wejścia/wyjścia. Dowolne
ingerowanie w elementy systemu musi być zabronione lub wykrywalne,
urządzenie może odmówić uruchomienia w przypadku przejęcia.
dm-crypt dla integralności
Pliki w kontenerze APEX pochodzą z wbudowanych partycji (na przykład
/system
partycji) chronionej przez dm-verity, gdzie każda modyfikacja
pliki są zabronione nawet po podłączeniu partycji. Aby udostępnić
poziom bezpieczeństwa plików, wszystkie pliki w raporcie APEX są przechowywane w formie pliku
obraz systemu sparowany z drzewem skrótu i deskryptorem vbmeta. Bez
dm-verity, punkt APEX w partycji /data
jest podatny na niezamierzone
modyfikacje wprowadzone po sprawdzeniu i zainstalowaniu.
W rzeczywistości partycja /data
jest również chroniona przez warstwy szyfrowania, takie jak
dm-crypt. Chociaż zapewnia to pewien poziom ochrony przed nieuprawnionymi modyfikacjami,
że ich głównym celem jest prywatność, a nie uczciwość. Gdy atakujący uzyska dostęp do
/data
, nie ma dodatkowej ochrony, a to znowu jest
w porównaniu z każdym komponentem systemu, który jest w partycji /system
.
Drzewo skrótu w pliku APEX w połączeniu z dm-verity daje taki sam efekt.
poziom ochrony treści.
Przekieruj ścieżki z /system do /apex
Pliki komponentów systemowych spakowane w APEX są dostępne za pomocą nowych ścieżek, takich jak
/apex/<name>/lib/libfoo.so
Kiedy pliki należały do folderu /system
partycji, były dostępne poprzez ścieżki takie jak /system/lib/libfoo.so
. O
klienta pliku APEX (innych plików APEX lub platformy) musi używać nowego
ścieżek konwersji. W wyniku zmiany ścieżki może być konieczna aktualizacja istniejącego kodu.
Chociaż jednym ze sposobów uniknięcia zmiany ścieżki jest nałożenie zawartości pliku
pliku APEX na partycję /system
, ale zespół Androida zdecydował się nie nakładać
na partycji /system
, bo może to wpłynąć na wydajność,
liczba nałożonych plików (może nawet nakładać się jeden po drugim);
wzrosła.
Inną możliwością było przejęcie funkcji dostępu do plików, takich jak open
, stat
czy
readlink
, dzięki czemu ścieżki zaczynające się od /system
były przekierowywane do
odpowiednich ścieżek w /apex
. Zespół Androida odrzucił tę opcję
bo nie można zmienić wszystkich funkcji, które akceptują ścieżki.
Na przykład niektóre aplikacje statycznie łączą się z Bionic, który implementuje te funkcje.
W takich przypadkach aplikacje nie są przekierowywane.