Android Pony EXpress (APEX) kapsayıcı biçimi, Android 10'da tanıtıldı ve alt düzey sistem modülleri için yükleme akışında kullanıldı. Bu biçim, standart Android uygulama modeline uymayan sistem bileşenlerinin güncellemelerini kolaylaştırır. Bazı örnek bileşenler, yerel hizmetler ve kitaplıklar, donanım soyutlama katmanları ( HAL'ler ), çalışma zamanı ( ART ) ve sınıf kitaplıklarıdır.
"APEX" terimi ayrıca bir APEX dosyasına atıfta bulunabilir.
Arka fon
Android, paket yükleyici uygulamaları (Google Play Store uygulaması gibi) aracılığıyla standart uygulama modeline (örneğin hizmetler, etkinlikler) uyan modüllerin güncellemelerini desteklese de, daha düşük düzeyli işletim sistemi bileşenleri için benzer bir model kullanmanın aşağıdaki dezavantajları vardır:
- APK tabanlı modüller, önyükleme sırasında erken kullanılamaz. Paket yöneticisi, uygulamalar hakkında merkezi bilgi deposudur ve yalnızca, önyükleme prosedürünün sonraki bir aşamasında hazır hale gelen etkinlik yöneticisinden başlatılabilir.
- APK formatı (özellikle manifesto), Android uygulamaları için tasarlanmıştır ve sistem modülleri her zaman uygun değildir.
Tasarım
Bu bölüm, APEX dosya formatının üst düzey tasarımını ve APEX dosyalarını yöneten bir hizmet olan APEX yöneticisini açıklar.
APEX için bu tasarımın neden seçildiği hakkında daha fazla bilgi için bkz. APEX geliştirilirken dikkate alınan alternatifler .
APEX formatı
Bu, bir APEX dosyasının biçimidir.
Şekil 1. APEX dosya formatı
En üst düzeyde, bir APEX dosyası, dosyaların sıkıştırılmamış olarak depolandığı ve 4 KB sınırlarında yer aldığı bir zip dosyasıdır.
Bir APEX dosyasındaki dört dosya şunlardır:
-
apex_manifest.json
-
AndroidManifest.xml
-
apex_payload.img
-
apex_pubkey
apex_manifest.json
dosyası, bir APEX dosyasını tanımlayan paket adını ve sürümünü içerir.
AndroidManifest.xml
dosyası, APEX dosyasının ADB, PackageManager ve paket yükleyici uygulamaları (Play Store gibi) gibi APK ile ilgili araçları ve altyapıyı kullanmasına izin verir. Örneğin, APEX dosyası, dosyadaki temel meta verileri incelemek için aapt
gibi mevcut bir aracı kullanabilir. Dosya, paket adı ve sürüm bilgilerini içerir. Bu bilgiler genellikle apex_manifest.json
da mevcuttur.
apex_manifest.json
, APEX ile ilgilenen yeni kod ve sistemler için AndroidManifest.xml
yerine önerilir. AndroidManifest.xml
, mevcut uygulama yayınlama araçları tarafından kullanılabilecek ek hedefleme bilgileri içerebilir.
apex_payload.img
, dm-verity tarafından desteklenen bir ext4 dosya sistemi görüntüsüdür. Görüntü, bir geri döngü aygıtı aracılığıyla çalışma zamanında monte edilir. Özellikle, hash ağacı ve meta veri bloğu, libavb
kitaplığı kullanılarak oluşturulur. Dosya sistemi yükü ayrıştırılmaz (çünkü görüntünün yerine monte edilebilir olması gerekir). apex_payload.img
dosyasının içinde normal dosyalar bulunur.
apex_pubkey
, dosya sistemi görüntüsünü imzalamak için kullanılan ortak anahtardır. Çalışma zamanında, bu anahtar, indirilen APEX'in yerleşik bölümlerde aynı APEX'i imzalayan aynı varlıkla imzalanmasını sağlar.
APEX adlandırma yönergeleri
Platform ilerledikçe yeni APEX'ler arasındaki adlandırma çakışmalarını önlemeye yardımcı olmak için aşağıdaki adlandırma yönergelerini kullanın:
-
com.android.*
- AOSP APEX'leri için ayrılmıştır. Herhangi bir şirkete veya cihaza özgü değildir.
-
com.<companyname>.*
- Bir şirket için rezerve edilmiştir. Potansiyel olarak o şirkete ait birden fazla cihaz tarafından kullanılıyor.
-
com.<companyname>.<devicename>.*
- Belirli bir cihaza (veya cihazların alt kümesine) özgü APEX'ler için ayrılmıştır.
APEX yöneticisi
APEX yöneticisi (veya apexd
), APEX dosyalarının doğrulanmasından, yüklenmesinden ve kaldırılmasından sorumlu bağımsız bir yerel işlemdir. Bu işlem başlatılır ve önyükleme sırasında erkenden hazırdır. APEX dosyaları normalde /system/apex
altındaki cihaza önceden yüklenmiştir. APEX yöneticisi, güncelleme yoksa varsayılan olarak bu paketleri kullanır.
Bir APEX'in güncelleme sırası PackageManager sınıfını kullanır ve aşağıdaki gibidir.
- Bir APEX dosyası, bir paket yükleyici uygulaması, ADB veya başka bir kaynak aracılığıyla indirilir.
- Paket yöneticisi kurulum prosedürünü başlatır. Dosyanın bir APEX olduğunu anladıktan sonra, paket yöneticisi kontrolü APEX yöneticisine aktarır.
- APEX yöneticisi APEX dosyasını doğrular.
- APEX dosyası doğrulanırsa, APEX yöneticisinin dahili veritabanı, APEX dosyasının bir sonraki önyüklemede etkinleştirildiğini yansıtacak şekilde güncellenir.
- Yükleme isteğinde bulunan kişi, başarılı paket doğrulamasının ardından bir yayın alır.
- Kuruluma devam etmek için sistem yeniden başlatılmalıdır.
Bir sonraki önyüklemede, APEX yöneticisi başlar, dahili veritabanını okur ve listelenen her APEX dosyası için aşağıdakileri yapar:
- APEX dosyasını doğrular.
- APEX dosyasından bir geri döngü aygıtı oluşturur.
- Geri döngü cihazının üstünde bir cihaz eşleyici blok cihazı oluşturur.
- Aygıt eşleyici blok aygıtını benzersiz bir yola bağlar (örneğin,
/apex/ name @ ver
).
Dahili veritabanında listelenen tüm APEX dosyaları bağlandığında, APEX yöneticisi diğer sistem bileşenlerinin kurulu APEX dosyaları hakkında bilgi sorgulaması için bir bağlayıcı hizmeti sağlar. Örneğin, diğer sistem bileşenleri, cihazda kurulu APEX dosyalarının listesini sorgulayabilir veya belirli bir APEX'in monte edildiği tam yolu sorgulayabilir, böylece dosyalara erişilebilir.
APEX dosyaları APK dosyalarıdır
APEX dosyaları, bir AndroidManifest.xml
dosyası içeren (APK imza şemasını kullanan) imzalı zip arşivleri oldukları için geçerli APK dosyalarıdır. Bu, APEX dosyalarının paket yükleyici uygulaması, imzalama yardımcı programı ve paket yöneticisi gibi APK dosyaları için altyapıyı kullanmasına olanak tanır.
Bir APEX dosyasının içindeki AndroidManifest.xml
dosyası minimum düzeydedir ve ayrıntılı hedefleme için paket name
, versionCode
ve isteğe bağlı targetSdkVersion
, minSdkVersion
ve maxSdkVersion
. Bu bilgi, APEX dosyalarının paket yükleyici uygulamaları ve ADB gibi mevcut kanallar aracılığıyla teslim edilmesini sağlar.
Desteklenen dosya türleri
APEX formatı şu dosya türlerini destekler:
- Yerel paylaşılan kitaplıklar
- Yerel yürütülebilir dosyalar
- JAR dosyaları
- Veri dosyaları
- Yapılandırma dosyaları
Bu, APEX'in tüm bu dosya türlerini güncelleyebileceği anlamına gelmez. Bir dosya türünün güncellenip güncellenemeyeceği, platforma ve dosya türleri için arayüz tanımlarının ne kadar kararlı olduğuna bağlıdır.
imza
APEX dosyaları iki şekilde imzalanır. İlk olarak, apex_payload.img
(özellikle apex_payload.img dosyasına eklenen apex_payload.img
tanımlayıcısı) dosyası bir anahtarla imzalanır. Ardından, APEX'in tamamı APK imza şeması v3 kullanılarak imzalanır. Bu işlemde iki farklı anahtar kullanılır.
Cihaz tarafında, vbmeta tanımlayıcısını imzalamak için kullanılan özel anahtara karşılık gelen bir genel anahtar kurulur. APEX yöneticisi, yüklenmesi istenen APEX'leri doğrulamak için ortak anahtarı kullanır. Her APEX farklı anahtarlarla imzalanmalıdır ve hem derleme zamanında hem de çalışma zamanında uygulanır.
APEX yerleşik bölümlerde
APEX dosyaları, /system
gibi yerleşik bölümlerde bulunabilir. Bölüm zaten dm-verity'nin üzerindedir, bu nedenle APEX dosyaları doğrudan geri döngü aygıtının üzerine monte edilir.
Yerleşik bir bölümde bir APEX varsa, APEX, aynı paket adına ve sürüm kodundan büyük veya ona eşit bir APEX paketi sağlanarak güncellenebilir. Yeni APEX, /data
içinde depolanır ve APK'lara benzer şekilde, yeni yüklenen sürüm, yerleşik bölümde zaten mevcut olan sürümü gölgeler. Ancak APK'ların aksine, APEX'in yeni yüklenen sürümü yalnızca yeniden başlatıldıktan sonra etkinleştirilir.
Çekirdek gereksinimleri
Bir Android cihazda APEX ana hat modüllerini desteklemek için aşağıdaki Linux çekirdeği özellikleri gereklidir: geri döngü sürücüsü ve dm-verity. Geri döngü sürücüsü, dosya sistemi görüntüsünü bir APEX modülüne bağlar ve dm-verity, APEX modülünü doğrular.
APEX modüllerini kullanırken iyi bir sistem performansı elde etmek için geri döngü sürücüsünün ve dm-verity'nin performansı önemlidir.
Desteklenen çekirdek sürümleri
APEX ana hat modülleri, 4.4 veya üzeri çekirdek sürümleri kullanan cihazlarda desteklenir. Android 10 veya üzeri ile piyasaya sürülen yeni cihazlar, APEX modüllerini desteklemek için çekirdek sürüm 4.9 veya üzerini kullanmalıdır.
Gerekli çekirdek yamaları
APEX modüllerini desteklemek için gerekli çekirdek yamaları Android ortak ağacında bulunur. Yamaların APEX'i desteklemesini sağlamak için Android ortak ağacının en son sürümünü kullanın.
Çekirdek sürümü 4.4
Bu sürüm yalnızca Android 9'dan Android 10'a yükseltilen ve APEX modüllerini desteklemek isteyen cihazlar için desteklenir. Gerekli yamaları almak için android-4.4
dalından aşağı birleştirme şiddetle tavsiye edilir. Aşağıda, çekirdek sürüm 4.4 için gerekli olan tek tek yamaların bir listesi bulunmaktadır.
- UPSTREAM: döngü: mantıksal blok boyutunu değiştirmek için ioctl ekleyin ( 4.4 )
- BACKPORT: blok/döngü: hw_sektörlerini ayarla ( 4.4 )
- UPSTREAM: döngü: ioctl uyumluluğuna LOOP_SET_BLOCK_SIZE ekleyin ( 4.4 )
- ANDROID: mnt: next_descendent'ı düzelt ( 4.4 )
- ANDROID: mnt: remount kölelerin kölelerine yayılmalıdır ( 4.4 )
- ANDROID: mnt: Yeniden montajı doğru bir şekilde yay ( 4.4 )
- "ANDROID: dm verity: minimum ön getirme boyutunu ekle"yi geri al ( 4.4 )
- UPSTREAM: loop: offset veya block_size değiştirilirse önbellekleri bırakın ( 4.4 )
Çekirdek sürümleri 4.9/4.14/4.19
Çekirdek sürümleri 4.9/4.14/4.19 için gerekli yamaları almak için android-common
dalından aşağı birleştirme yapın.
Gerekli çekirdek yapılandırma seçenekleri
Aşağıdaki liste, Android 10'da tanıtılan APEX modüllerini desteklemek için temel yapılandırma gereksinimlerini gösterir. Yıldız (*) içeren öğeler, Android 9 ve daha düşük sürümlerde mevcut gereksinimlerdir.
(*) 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
Çekirdek komut satırı parametre gereksinimleri
APEX'i desteklemek için çekirdek komut satırı parametrelerinin aşağıdaki gereksinimleri karşıladığından emin olun:
-
loop.max_loop
-
loop.max_part
<= 8 olmalıdır
APEX inşa etmek
Bu bölüm, Android derleme sistemini kullanarak bir APEX'in nasıl oluşturulacağını açıklar. Aşağıda apex.test
adlı bir APEX için Android.bp
örneği verilmiştir.
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",
}
apex_manifest.json
örneği:
{
"name": "com.android.example.apex",
"version": 1
}
file_contexts
örneği:
(/.*)? u:object_r:system_file:s0
/sub(/.*)? u:object_r:sub_file:s0
/sub/file3 u:object_r:file3_file:s0
APEX'teki dosya türleri ve konumları
Dosya tipi | APEX'teki konum |
---|---|
Paylaşılan kitaplıklar | /lib ve /lib64 (x86'da çevrilmiş kol için /lib/arm ) |
Yürütülebilir dosyalar | /bin |
Java kitaplıkları | /javalib |
önceden oluşturulmuş | /etc |
Geçişli bağımlılıklar
APEX dosyaları, yerel paylaşılan kitaplıkların veya yürütülebilir dosyaların geçişli bağımlılıklarını otomatik olarak içerir. Örneğin, libFoo
libBar
, native_shared_libs
özelliğinde yalnızca libFoo
listelendiğinde iki kitaplık dahil edilir.
Birden çok ABI'yi işleme
Aygıtın hem birincil hem de ikincil uygulama ikili arabirimleri (ABI'ler) için native_shared_libs
özelliğini yükleyin. Bir APEX, tek bir ABI'ye sahip cihazları hedefliyorsa (yani, yalnızca 32 bit veya yalnızca 64 bit), yalnızca ilgili ABI'ye sahip kitaplıklar yüklenir.
binaries
özelliğini yalnızca aşağıda açıklandığı gibi aygıtın birincil ABI'si için yükleyin:
- Aygıt yalnızca 32 bit ise, ikili programın yalnızca 32 bitlik sürümü kurulur.
- Aygıt yalnızca 64 bit ise, ikili programın yalnızca 64 bit çeşidi yüklenir.
Yerel kitaplıkların ve ikili dosyaların ABI'leri üzerinde ayrıntılı denetim eklemek için multilib.[first|lib32|lib64|prefer32|both].[native_shared_libs|binaries]
özelliklerini kullanın.
-
first
: Cihazın birincil ABI'si ile eşleşir. Bu, ikili dosyalar için varsayılandır. -
lib32
: Destekleniyorsa, cihazın 32 bit ABI'si ile eşleşir. -
lib64
: Cihazın 64-bit ABI'si ile eşleşir, desteklediği. -
prefer32
: Destekleniyorsa, cihazın 32 bit ABI'si ile eşleşir. 32 bit ABI desteklenmiyorsa 64 bit ABI ile eşleşir. - Both : Her
both
ABI ile eşleşir. Bu,native_shared_libraries
için varsayılandır.
java
, libraries
ve prebuilts
özellikler ABI-agnostiktir.
Bu örnek, 32/64'ü destekleyen ve 32'yi tercih etmeyen bir cihaz içindir:
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
},
},
}
vbmeta imzalama
Her APEX'i farklı tuşlarla imzalayın. Yeni bir anahtar gerektiğinde, bir genel-özel anahtar çifti oluşturun ve bir apex_key
modülü yapın. Anahtarı kullanarak APEX'i imzalamak için key
özelliğini kullanın. Genel anahtar, avb_pubkey adıyla avb_pubkey
otomatik olarak dahil edilir.
# 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", }
Yukarıdaki örnekte, genel anahtarın adı ( foo
) anahtarın kimliği olur. Bir APEX'i imzalamak için kullanılan anahtarın kimliği APEX'te yazılmıştır. Çalışma zamanında apexd, cihazda aynı kimliğe sahip bir ortak anahtar kullanarak apexd
doğrular.
posta imzalama
APEX'leri APK'ları imzaladığınız gibi imzalayın. APEX'leri iki kez imzalayın; mini dosya sistemi için bir kez ( apex_payload.img
dosyası) ve tüm dosya için bir kez.
Dosya düzeyinde bir APEX imzalamak için, certificate
özelliğini şu üç yoldan biriyle ayarlayın:
- Ayarlanmadı: Herhangi bir değer ayarlanmazsa, APEX,
PRODUCT_DEFAULT_DEV_CERTIFICATE
adresinde bulunan sertifika ile imzalanır. Bayrak ayarlanmazsa, yol varsayılan olarakbuild/target/product/security/testkey
. -
<name>
: APEX,PRODUCT_DEFAULT_DEV_CERTIFICATE
ile aynı dizinde<name>
sertifikasıyla imzalanmıştır. -
:<name>
: APEX,<name>
adlı Soong modülü tarafından tanımlanan sertifika ile imzalanmıştır. Sertifika modülü aşağıdaki gibi tanımlanabilir.
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)
}
APEX yükleme
Bir APEX kurmak için ADB'yi kullanın.
adb install apex_file_name
adb reboot
APEX kullanma
Yeniden başlatmanın ardından APEX, /apex/<apex_name>@<version>
dizinine bağlanır. Aynı APEX'in birden fazla versiyonu aynı anda monte edilebilir. Bağlama yolları arasında, en son sürüme karşılık gelen, /apex/<apex_name>
bind-mount edilir.
İstemciler, APEX'ten dosya okumak veya yürütmek için bağlama bağlantılı yolu kullanabilir.
APEX'ler tipik olarak şu şekilde kullanılır:
- Bir OEM veya ODM, aygıt sevk edildiğinde
/system/apex
altında bir APEX'i önceden yükler. - APEX'teki dosyalara
/apex/<apex_name>/
yolu üzerinden erişilir. - APEX'in güncellenmiş bir sürümü
/data/apex
içine yüklendiğinde, yol yeniden başlatıldıktan sonra yeni APEX'i gösterir.
APEX ile bir hizmeti güncelleme
APEX kullanarak bir hizmeti güncellemek için:
Hizmeti sistem bölümünde güncellenebilir olarak işaretleyin. Hizmet tanımına
updatable
seçeneğini ekleyin./system/etc/init/myservice.rc: service myservice /system/bin/myservice class core user system ... updatable
Güncellenen hizmet için yeni bir
.rc
dosyası oluşturun. Mevcut hizmeti yeniden tanımlamak içinoverride
seçeneğini kullanın./apex/my.apex/etc/init.rc: service myservice /apex/my.apex/bin/myservice class core user system ... override
Hizmet tanımları yalnızca bir APEX'in .rc
dosyasında tanımlanabilir. Eylem tetikleyicileri APEX'lerde desteklenmez.
APEX'ler etkinleştirilmeden önce güncellenebilir olarak işaretlenen bir hizmet başlarsa, başlatma APEX'lerin etkinleştirilmesi tamamlanana kadar ertelenir.
APEX güncellemelerini desteklemek için sistemi yapılandırma
APEX dosya güncellemelerini desteklemek için aşağıdaki sistem özelliğini true
olarak ayarlayın.
<device.mk>:
PRODUCT_PROPERTY_OVERRIDES += ro.apex.updatable=true
BoardConfig.mk:
TARGET_FLATTEN_APEX := false
ya da sadece
<device.mk>:
$(call inherit-product, $(SRC_TARGET_DIR)/product/updatable_apex.mk)
Düzleştirilmiş APEX
Eski cihazlar için, eski çekirdeği APEX'i tam olarak destekleyecek şekilde güncellemek bazen imkansız veya mümkün değildir. Örneğin, çekirdek CONFIG_BLK_DEV_LOOP=Y
olmadan oluşturulmuş olabilir; bu, dosya sistemi görüntüsünü bir APEX içine yerleştirmek için çok önemlidir.
Flattened APEX, eski bir çekirdeğe sahip cihazlarda etkinleştirilebilen özel olarak oluşturulmuş bir APEX'tir. Düzleştirilmiş bir APEX'teki dosyalar, yerleşik bölümün altındaki bir dizine doğrudan yüklenir. Örneğin, düzleştirilmiş bir lib/libFoo.so
my.apex
, /system/apex/my.apex/lib/libFoo.so
dizinine yüklenir.
Düzleştirilmiş bir APEX'in etkinleştirilmesi, döngü cihazını içermez. /system/apex/my.apex
dizininin tamamı doğrudan /apex/name@ver
dizinine bağlanır.
İndirilen APEX'ler düzleştirilemediğinden, düzleştirilmiş APEX'ler ağdan APEX'lerin güncel sürümleri indirilerek güncellenemez. Düzleştirilmiş APEX'ler yalnızca normal bir OTA aracılığıyla güncellenebilir.
Düzleştirilmiş APEX varsayılan yapılandırmadır. Bu, cihazınızı APEX güncellemelerini desteklemek için (yukarıda açıklandığı gibi) düzleştirilmemiş APEX'ler oluşturacak şekilde açıkça yapılandırmadığınız sürece, tüm APEX'lerin varsayılan olarak düzleştirildiği anlamına gelir.
Bir cihazda düzleştirilmiş ve düzleştirilmemiş APEX'lerin karıştırılması DESTEKLENMEZ. Bir cihazdaki APEX'lerin tümü düzleştirilmemiş veya tümü düzleştirilmiş olmalıdır. Bu, özellikle Mainline gibi projeler için önceden imzalanmış APEX ön kurulumlarını gönderirken önemlidir. Önceden imzalanmamış (yani kaynaktan oluşturulmuş) APEX'ler de düzleştirilmemeli ve uygun anahtarlarla imzalanmalıdır. Cihaz, Updatable_apex.mk'den APEX ile bir hizmeti updatable_apex.mk
bölümünde açıklandığı gibi devralmalıdır.
Sıkıştırılmış APEX'ler
Android 12 ve sonraki sürümleri, güncellenebilir APEX paketlerinin depolama etkisini azaltmak için APEX sıkıştırma özelliğine sahiptir. Bir APEX güncellemesi yüklendikten sonra, önceden yüklenmiş sürümü artık kullanılmasa da, yine de aynı miktarda yer kaplar. Bu işgal edilen alan kullanılamaz durumda kalır.
APEX sıkıştırması, salt okunur bölümlerde ( /system
bölümü gibi) yüksek düzeyde sıkıştırılmış bir APEX dosyası kümesi kullanarak bu depolama etkisini en aza indirir. Android 12 ve sonraki sürümleri bir DEFLATE zip sıkıştırma algoritması kullanır.
Sıkıştırma, aşağıdakiler için optimizasyon sağlamaz:
Önyükleme sırasında çok erken monte edilmesi gereken önyükleme APEX'leri.
Güncellenemeyen APEX'ler. Sıkıştırma, yalnızca
/data
bölümünde bir APEX'in güncellenmiş bir sürümü yüklüyse faydalıdır. Modüler Sistem Bileşenleri sayfasında güncellenebilir APEX'lerin tam listesi mevcuttur.Dinamik paylaşılan kütüphaneler APEX'ler.
apexd
, bu tür APEX'lerin (önceden yüklenmiş ve yükseltilmiş) her iki sürümünü de her zaman etkinleştirdiğinden, bunları sıkıştırmak değer katmaz.
Sıkıştırılmış APEX dosya biçimi
Bu, sıkıştırılmış bir APEX dosyasının biçimidir.
Şekil 2. Sıkıştırılmış APEX dosya formatı
En üst düzeyde, sıkıştırılmış bir APEX dosyası, sıkıştırma düzeyi 9 olan orijinal apex dosyasını sönük biçimde ve sıkıştırılmamış olarak depolanan diğer dosyaları içeren bir zip dosyasıdır.
Dört dosya bir APEX dosyasından oluşur:
-
original_apex
: sıkıştırma seviyesi 9 ile söndürülmüş Bu orijinal, sıkıştırılmamış APEX dosyasıdır . -
apex_manifest.pb
: yalnızca depolanır -
AndroidManifest.xml
: yalnızca depolanır -
apex_pubkey
: yalnızca depolanır
apex_manifest.pb
, AndroidManifest.xml
ve apex_pubkey
dosyaları, original_apex
içindeki karşılık gelen dosyalarının kopyalarıdır.
Sıkıştırılmış APEX oluşturma
Sıkıştırılmış APEX, system/apex/tools
konumunda bulunan apex_compression_tool.py
aracı kullanılarak oluşturulabilir.
APEX sıkıştırmasıyla ilgili çeşitli parametreler, derleme sisteminde mevcuttur.
Android.bp
bir APEX dosyasının sıkıştırılabilir olup olmadığı compressible
özellik tarafından kontrol edilir:
apex {
name: "apex.test",
manifest: "apex_manifest.json",
file_contexts: "file_contexts",
compressible: true,
}
PRODUCT_COMPRESSED_APEX
ürün bayrağı, kaynaktan oluşturulan bir sistem görüntüsünün sıkıştırılmış APEX dosyaları içermesi gerekip gerekmediğini denetler.
Yerel deneme için, OVERRIDE_PRODUCT_COMPRESSED_APEX=
öğesini true
olarak ayarlayarak bir yapıyı APEX'leri sıkıştırmaya zorlayabilirsiniz.
Derleme sistemi tarafından oluşturulan sıkıştırılmış APEX dosyaları .capex
uzantısına sahiptir. Uzantı, bir APEX dosyasının sıkıştırılmış ve sıkıştırılmamış sürümleri arasında ayrım yapmayı kolaylaştırır.
Desteklenen sıkıştırma algoritmaları
Android 12 yalnızca deflate-zip sıkıştırmasını destekler.
Önyükleme sırasında sıkıştırılmış bir APEX dosyasını etkinleştirme
Sıkıştırılmış bir APEX etkinleştirilmeden önce, içindeki original_apex
dosyası /data/apex/decompressed
dizine açılır. Ortaya çıkan sıkıştırılmış APEX dosyası, /data/apex/active
dizinine sabit bağlantılıdır.
Aşağıdaki örneği, yukarıda açıklanan işlemin bir örneği olarak düşünün.
/system/apex/com.android.foo.capex
sürüm Kodu 37 ile etkinleştirilen sıkıştırılmış bir APEX olarak düşünün.
-
/system/apex/com.android.foo.capex
içindekioriginal_apex
dosyası,/data/apex/decompressed/com.android.foo@37.apex
olarak açılır. -
restorecon /data/apex/decompressed/com.android.foo@37.apex
doğru bir SELinux etiketine sahip olduğunu doğrulamak için gerçekleştirilir. - Geçerliliğini sağlamak için
/data/apex/decompressed/com.android.foo@37.apex
doğrulama kontrolleri gerçekleştirilir:apexd
,/data/apex/decompressed/com.android.foo@37.apex
içinde paketlenmiş genel anahtarı kontrol eder./system/apex/com.android.foo.capex
içinde paketlenmiş olana eşit olduğunu doğrulayın. -
/data/apex/decompressed/com.android.foo@37.apex
dosyası/data/apex/active/com.android.foo@37.apex
dizinine sabit bağlantılıdır. - Sıkıştırılmamış APEX dosyaları için normal aktivasyon mantığı,
/data/apex/active/com.android.foo@37.apex
üzerinde gerçekleştirilir.
OTA ile etkileşim
Sıkıştırılmış APEX dosyalarının OTA dağıtımı ve uygulaması üzerinde etkileri vardır. Bir OTA güncellemesi, bir cihazda etkin olandan daha yüksek bir sürüm düzeyine sahip sıkıştırılmış bir APEX dosyası içerebileceğinden, bir OTA güncellemesini uygulamak için bir cihaz yeniden başlatılmadan önce belirli bir miktarda boş alan ayrılmalıdır.
OTA sistemini desteklemek için apexd
, şu iki bağlayıcı API'yi sunar:
-
calculateSizeForCompressedApex
- bir OTA paketindeki APEX dosyalarını açmak için gereken boyutu hesaplar. Bu, bir OTA indirilmeden önce bir cihazın yeterli alana sahip olduğunu doğrulamak için kullanılabilir. -
reserveSpaceForCompressedApex
- OTA paketi içindeki sıkıştırılmış APEX dosyalarını açmak içinapexd
tarafından gelecekte kullanılmak üzere diskte yer ayırır.
A/B OTA güncellemesi durumunda, apexd
, yükleme sonrası OTA rutininin bir parçası olarak arka planda sıkıştırmayı açmayı dener. Dekompresyon başarısız olursa, apexd
, OTA güncellemesini uygulayan önyükleme sırasında açma işlemini gerçekleştirir.
APEX geliştirirken dikkate alınan alternatifler
AOSP'nin APEX dosya biçimini tasarlarken göz önünde bulundurduğu bazı seçenekler ve neden dahil edildikleri veya hariç tutuldukları.
Düzenli paket yönetim sistemleri
Linux dağıtımları, güçlü, olgun ve sağlam olan dpkg
ve rpm
gibi paket yönetim sistemlerine sahiptir. Ancak, kurulumdan sonra paketleri koruyamadıkları için APEX için kabul edilmediler. Doğrulama yalnızca paketler kurulurken gerçekleştirilir. Saldırganlar, fark edilmeden kurulu paketlerin bütünlüğünü bozabilir. Bu, tüm sistem bileşenlerinin bütünlüğü her G/Ç için dm-verity tarafından korunan salt okunur dosya sistemlerinde depolandığı Android için bir gerilemedir. Sistem bileşenlerine yapılacak herhangi bir kurcalama ya yasaklanmalı ya da aygıtın güvenliği ihlal edildiğinde önyüklemeyi reddedebilmesi için algılanabilir olmalıdır.
bütünlük için dm-crypt
Bir APEX kapsayıcısındaki dosyalar, dm-verity tarafından korunan yerleşik bölümlerdendir (örneğin, /system
bölümü). Dosyalara aynı düzeyde güvenlik sağlamak için, bir APEX'teki tüm dosyalar, bir hash ağacı ve bir vbmeta tanımlayıcısı ile eşleştirilmiş bir dosya sistemi görüntüsünde saklanır. dm-verity olmadan, /data
bölümündeki bir APEX, doğrulandıktan ve yüklendikten sonra yapılan istenmeyen değişikliklere karşı savunmasızdır.
Aslında, /data
bölümü de dm-crypt gibi şifreleme katmanlarıyla korunur. Bu, kurcalamaya karşı bir düzeyde koruma sağlasa da, birincil amacı bütünlük değil gizliliktir. Bir saldırgan /data
bölümüne erişim kazandığında, daha fazla koruma olamaz ve bu da /system
bölümündeki her sistem bileşenine kıyasla bir gerilemedir. APEX dosyasının içindeki hash ağacı, dm-verity ile birlikte aynı düzeyde içerik koruması sağlar.
Yolları /system'den /apex'e yönlendirme
Bir APEX'te paketlenmiş sistem bileşeni dosyalarına /apex/<name>/lib/libfoo.so
gibi yeni yollarla erişilebilir. Dosyalar /system
bölümünün bir parçası olduğunda, bunlara /system/lib/libfoo.so
gibi yollardan erişilebilirdi. Bir APEX dosyasının istemcisi (diğer APEX dosyaları veya platform) yeni yolları kullanmalıdır. Yol değişikliğinin bir sonucu olarak mevcut kodu güncellemeniz gerekebilir.
Yol değişikliğinden kaçınmanın bir yolu, bir APEX dosyasındaki dosya içeriklerini /system
bölümüne bindirmek olsa da, Android ekibi dosyaları /system
bölümünde kaplamamaya karar verdi, çünkü bu, bindirilen dosya sayısı olarak performansı etkileyebilir ( muhtemelen birbiri ardına istiflenmiş bile) arttı.
Başka bir seçenek de open
, stat
ve readlink
gibi dosya erişim işlevlerini ele geçirmekti, böylece /system
ile başlayan yollar /apex
altındaki karşılık gelen yollarına yönlendirildi. Android ekibi, yolları kabul eden tüm işlevleri değiştirmek mümkün olmadığı için bu seçeneği reddetti. Örneğin, bazı uygulamalar, işlevleri uygulayan Bionic'i statik olarak bağlar. Bu gibi durumlarda, bu uygulamalar yeniden yönlendirilmez.