Android Pony EXpress (APEX) kapsayıcı biçimi Android 10'da kullanıma sunuldu ve alt düzey sistem modülleri için yükleme akışında kullanılır. Bu biçim, standart Android uygulama modeline uymayan sistem bileşenlerinin güncellenmesini kolaylaştırır. Yerel hizmetler ve kitaplıklar, donanım soyutlama katmanları (HAL'ler), çalışma zamanı (ART) ve sınıf kitaplıkları örnek bileşenlere örnek olarak verilebilir.
"APEX" terimi, APEX dosyasını da ifade edebilir.
Arka plan
Android, paket yükleyici uygulamaları (Google Play Store uygulaması gibi) aracılığıyla standart uygulama modeline uyan modüllerin güncellemelerini (örneğin, hizmetler, etkinlikler) destekliyor olsa da alt düzey 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ının başlarında kullanılamaz. Paket yöneticisi, uygulamalarla ilgili bilgilerin merkezi deposudur ve yalnızca önyükleme işleminin sonraki bir aşamasında hazır hale gelen etkinlik yöneticisinden başlatılabilir.
- APK biçimi (özellikle manifest), Android uygulamaları için tasarlanmıştır ve sistem modülleri her zaman uygun olmayabilir.
Tasarım
Bu bölümde, APEX dosya biçiminin ve APEX dosyalarını yöneten bir hizmet olan APEX yöneticisinin üst düzey tasarımı açıklanmaktadır.
APEX için bu tasarımın neden seçildiğiyle ilgili daha fazla bilgi için APEX geliştirilirken dikkate alınan alternatifler bölümüne bakın.
APEX biçimi
Bu, APEX dosyasının biçimidir.
Şekil 1. APEX dosyası biçimi
Üst düzeyde bir APEX dosyası, dosyaların sıkıştırılmadan depolandığı ve 4 KB sınırlarında bulunduğu 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ı, APEX dosyasını tanımlayan paket adını ve sürümünü içerir. Bu, JSON biçiminde bir ApexManifest
protokol arabelleğidir.
AndroidManifest.xml
dosyası, APEX dosyasının APK ile ilgili araçları ve altyapıyı (ör. ADB, PackageManager ve paket yükleyici uygulamaları (ör. Play Store)) kullanmasına olanak tanır. Örneğin, APEX dosyası, dosyadaki temel meta verileri incelemek için aapt
gibi mevcut bir aracı kullanabilir. Dosya, paket adını ve sürüm bilgilerini içerir. Bu bilgiler genellikle apex_manifest.json
içinde de mevcuttur.
APEX ile çalışan yeni kod ve sistemler için AndroidManifest.xml
yerine apex_manifest.json
ö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ü, çalışma zamanında geri döngü cihazı aracılığıyla eklenir. Özellikle karma 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ü yerinde monte edilebilir olmalıdır). Normal dosyalar apex_payload.img
dosyasına dahil edilir.
apex_pubkey
, dosya sistemi görüntüsünü imzalamak için kullanılan ortak anahtardır. Bu anahtar, çalışma zamanında indirilen APEX'in yerleşik bölümlerdeki aynı APEX'i imzalayan tüzel kişiyle imzalanmasını sağlar.
APEX adlandırma kuralları
Platform geliştikçe yeni APEX'ler arasında adlandırma çakışmalarını önlemek için aşağıdaki adlandırma kurallarına uyun:
com.android.*
- AOSP APEX'leri için ayrılmıştır. Herhangi bir şirkete veya cihaza özel değildir.
com.<companyname>.*
- Bir şirket için ayrılmış. Söz konusu şirketten birden fazla cihaz tarafından kullanılıyor olabilir.
com.<companyname>.<devicename>.*
- Belirli bir cihaza (veya cihaz alt kümesine) özel APEX'ler için ayrılır.
APEX yöneticisi
APEX yöneticisi (veya apexd
), APEX dosyalarını doğrulamaktan, yüklemekten ve kaldırmaktan sorumlu bağımsız bir yerel işlemdir. Bu işlem başlatılır ve başlatma
sırasının başlarında hazır olur. APEX dosyaları genellikle cihaza /system/apex
altında önceden yüklenmiştir. APEX yöneticisi, herhangi bir güncelleme yoksa varsayılan olarak bu paketleri kullanır.
APEX'in güncelleme sırası PackageManager sınıfını kullanır ve aşağıdaki gibidir.
- APEX dosyası, bir paket yükleyici uygulaması, ADB veya başka bir kaynak üzerinden indirilir.
- Paket yöneticisi, yükleme işlemini başlatır. Paket yöneticisi, dosyanın APEX olduğunu anladığında 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 başlatmada etkinleştirileceğini yansıtacak şekilde güncellenir.
- Yükleme isteğinde bulunan kullanıcı, başarılı paket doğrulamasının ardından bir yayın alır.
- Yükleme işlemine devam etmek için sistemin yeniden başlatılması gerekir.
Bir sonraki başlatmada 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 geri döngü cihazı oluşturur.
- Döngüsel cihazın üzerine bir cihaz eşleyici blok cihazı oluşturur.
- Cihaz eşleyici blok cihazını benzersiz bir yola (örneğin,
/apex/name@ver
) ekler.
Dahili veritabanında listelenen tüm APEX dosyaları monte edildiğinde APEX yöneticisi, diğer sistem bileşenlerinin yüklü APEX dosyaları hakkında bilgi sorgulamasına olanak tanıyan bir bağlayıcı hizmeti sağlar. Örneğin, diğer sistem bileşenleri cihaza yüklenen APEX dosyalarının listesini veya belirli bir APEX'in monte edildiği tam yolu sorgulayabilir. Böylece dosyalara erişilebilir.
APEX dosyaları APK dosyalarıdır
APEX dosyaları, AndroidManifest.xml
dosyası içeren imzalanmış zip arşivleri (APK imza şeması kullanılarak) oldukları için geçerli APK dosyalarıdır. Bu şekilde APEX dosyaları, APK dosyaları için paket yükleyici uygulaması, imzalama yardımcı programı ve paket yöneticisi gibi altyapıyı kullanabilir.
APEX dosyasındaki AndroidManifest.xml
dosyası minimum düzeydedir ve name
paketi, versionCode
ve isteğe bağlı olarak ayrıntılı hedefleme için targetSdkVersion
, minSdkVersion
ve maxSdkVersion
dosyalarından oluşur. Bu bilgiler, APEX dosyalarının paket yükleyici uygulamaları ve ADB gibi mevcut kanallar üzerinden dağıtılmasına olanak tanır.
Desteklenen dosya türleri
APEX biçimi ş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 bu dosya türlerinin tümünü güncelleyebileceği anlamına gelmez. Bir dosya türünün güncellenip güncellenmeyeceği platforma ve dosya türleri arayüzlerinin tanımlarının ne kadar kararlı olduğuna bağlıdır.
İmzalama seçenekleri
APEX dosyaları iki şekilde imzalanır. İlk olarak, apex_payload.img
(özellikle apex_payload.img
öğesine eklenen vbmeta tanımlayıcı) 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ı imzalamak için kullanılan özel anahtara karşılık gelen bir ortak anahtar yüklenir. 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.
Yerleşik bölümlerde APEX
APEX dosyaları, /system
gibi yerleşik bölümlerde bulunabilir. Bölüm zaten dm-verity üzerinde olduğundan APEX dosyaları doğrudan döngü cihazına monte edilir.
Yerleşik bir bölümde APEX varsa aynı paket adına ve sürüm kodundan daha büyük veya eşit bir APEX paketi sağlayarak APEX 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 bulunan sürümü gölgeler. Ancak APK'ların aksine, APEX'in yeni yüklenen sürümü yalnızca yeniden başlatmadan sonra etkinleştirilir.
Çekirdek gereksinimleri
Android cihazlarda APEX ana hat modüllerini desteklemek için şu Linux çekirdek ö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 ekler ve dm-verity, APEX modülünü doğrular.
APEX modülleri kullanılırken iyi bir sistem performansı elde etmek için döngüsel sürücünün ve dm-verity'nin performansı önemlidir.
Desteklenen çekirdek sürümleri
APEX ana hat modülleri, çekirdek 4.4 veya üzeri sürümleri kullanan cihazlarda desteklenir. Android 10 veya sonraki sürümlerin yüklü olduğu yeni cihazların, APEX modüllerini desteklemek için çekirdek 4.9 veya sonraki sürümleri kullanması gerekir.
Zorunlu çekirdek yamaları
APEX modüllerini desteklemek için gereken çekirdek yamaları, Android ortak ağacına dahil edilmiştir. 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ükseltilmiş ve APEX modüllerini desteklemek isteyen cihazlar için desteklenir. Gerekli yamaları almak için android-4.4
dalından aşağı birleştirme işlemi kesinlikle önerilir. Aşağıda, çekirdek 4.4 sürümü için gerekli olan bağımsız yamaların listesi verilmiştir.
- UPSTREAM: loop: add ioctl for changing logical block size (4.4)
- BACKPORT: block/loop: set hw_sectors (4.4)
- UPSTREAM: döngü: Uyumlu ioctl'e LOOP_SET_BLOCK_SIZE ekleyin (4,4)
- ANDROID: mnt: next_descendent'i düzeltin (4.4)
- ANDROID: mnt: remount should propagate to slaves of slaves (4.4)
- ANDROID: mnt: Yeniden bağlama işlemini doğru şekilde yayma (4.4)
- "ANDROID: dm sürümü: Minimum önceden getirme boyutunu ekleyin" işlemini geri döndürün (4.4)
- UPSTREAM: loop: offset veya block_size değişirse önbellekleri bırak (4.4)
Kernel sürümleri 4.9/4.14/4.19
4.9/4.14/4.19 çekirdek sürümleri için gerekli yamaları almak üzere android-common
dalından aşağı doğru birleştirme yapın.
Gerekli çekirdek yapılandırma seçenekleri
Aşağıdaki listede, Android 10'da kullanıma sunulan APEX modüllerini desteklemek için gereken temel yapılandırma gereksinimleri gösterilmektedir. Yıldız işareti (*) içeren öğeler, Android 9 ve önceki sürümlerde geçerli olan şartlardır.
(*) 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ı parametresi koşulları
APEX'i desteklemek için çekirdek komut satırı parametrelerinin aşağıdaki koşulları karşıladığından emin olun:
loop.max_loop
AYARLANMAMALIDIRloop.max_part
8'den küçük olmalıdır
APEX oluşturma
Bu bölümde, Android derleme sistemini kullanarak APEX'in nasıl derleneceği açıklanmaktadır.
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 türü | APEX'teki konum |
---|---|
Paylaşılan kitaplıklar | /lib ve /lib64 (x86'da çevrilen kol için /lib/arm ) |
Yürütülebilir dosyalar | /bin |
Java kitaplıkları | /javalib |
Hazır sistemler | /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
öğesine bağlıysa native_shared_libs
özelliğinde yalnızca libFoo
listelendiğinde iki kitaplık da dahil edilir.
Birden fazla ABI'yi yönetme
Cihazın hem birincil hem de ikincil uygulama ikili arayüzleri (ABI'ler) için native_shared_libs
özelliğini yükleyin. Bir APEX tek bir ABI'ye sahip cihazları (ör. yalnızca 32 bit veya yalnızca 64 bit) hedefliyorsa yalnızca ilgili ABI'ye sahip kitaplıklar yüklenir.
binaries
özelliğini yalnızca cihazın birincil ABI'si için aşağıda açıklandığı şekilde yükleyin:
- Cihaz yalnızca 32 bitse ikili programın yalnızca 32 bit varyantı yüklenir.
- Cihaz yalnızca 64 bit ise ikili dosyanın yalnızca 64 bit varyantı yüklenir.
Yerel kitaplıkların ve ikili programların ABI'leri üzerinde ayrıntılı kontrol eklemek için multilib.[first|lib32|lib64|prefer32|both].[native_shared_libs|binaries]
özelliklerini kullanın.
first
: Cihazın birincil ABI'siyle eşleşir. Bu, ikili dosyalar için varsayılan ayardır.lib32
: Destekleniyorsa cihazın 32 bit ABI'siyle eşleşir.lib64
: Cihazın 64 bit ABI'siyle eşleşiyor, desteklenir.prefer32
: Destekleniyorsa cihazın 32 bit ABI'siyle eşleşir. 32 bit ABI desteklenmiyorsa 64 bit ABI ile eşleşir.both
: Her iki ABI ile eşleşir. Bu,native_shared_libraries
için varsayılan değerdir.
java
, libraries
ve prebuilts
özellikleri ABI'den bağımsızdır.
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 imza
Her APEX'i farklı anahtarlarla imzalayın. Yeni bir anahtar gerektiğinde herkese açık-özel anahtar çifti oluşturun ve bir apex_key
modülü oluşturun. Anahtarı kullanarak APEX'i imzalamak için key
mülkünü kullanın. Ortak anahtar, APEX'e otomatik olarak avb_pubkey
adıyla eklenir.
# 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 ortak anahtarın adı (foo
) anahtarın kimliği olur. APEX'i imzalamak için kullanılan anahtarın kimliği APEX'te yazılır. Çalışma zamanında apexd
, cihazdaki aynı kimliğe sahip bir ortak anahtar kullanarak APEX'i doğrular.
APEX imzalama
APEX'leri, APK'ları imzaladığınız şekilde imzalayın. APEX'leri iki kez imzalayın: mini dosya sistemi (apex_payload.img
dosyası) için bir kez ve dosyanın tamamı için bir kez.
Bir APEX'i dosya düzeyinde imzalamak için certificate
özelliğini aşağıdaki üç yöntemden biriyle ayarlayın:
- Ayarlanmadı: Herhangi bir değer ayarlanmazsa APEX,
PRODUCT_DEFAULT_DEV_CERTIFICATE
adresinde bulunan sertifikayla imzalanır. Hiçbir işaret ayarlanmadıysa yol varsayılan olarakbuild/target/product/security/testkey
olur. <name>
: APEX,PRODUCT_DEFAULT_DEV_CERTIFICATE
ile aynı dizinde bulunan<name>
sertifikasıyla imzalanmıştır.:<name>
: APEX,<name>
adlı Soong modülü tarafından tanımlanan sertifikayla imzalanı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
APEX yüklemek için ADB'yi kullanın.
adb install apex_file_name
adb reboot
supportsRebootlessUpdate
, apex_manifest.json
içinde true
olarak ayarlanmışsa ve şu anda yüklü olan APEX kullanılmamışsa (örneğin, içerdiği tüm hizmetler durdurulmuşsa) yeni bir APEX, --force-non-staged
işaretiyle yeniden başlatılmadan yüklenebilir.
adb install --force-non-staged apex_file_name
APEX kullanma
Yeniden başlatıldıktan sonra APEX, /apex/<apex_name>@<version>
dizinine eklenir. Aynı APEX'in birden çok sürümü aynı anda eklenebilir.
En son sürüme karşılık gelen ekleme yolu, /apex/<apex_name>
adresinde bağlanarak eklenir.
İstemciler, bağlama eklenen yolu APEX'ten dosya okumak veya yürütmek için kullanabilir.
APEX'ler genellikle aşağıdaki şekilde kullanılır:
- Cihaz gönderildiğinde OEM veya ODM bir APEX'i
/system/apex
altında önceden yükler. - APEX'teki dosyalara
/apex/<apex_name>/
yolu üzerinden erişilir. /data/apex
'e APEX'in güncellenmiş bir sürümü yüklendiğinde, yeniden başlatma işleminden sonra yol yeni APEX'i gösterir.
APEX ile hizmet güncelleme
Bir hizmeti APEX kullanarak güncellemek için:
Sistem bölümünde hizmeti güncellenebilir olarak işaretleyin.
updatable
seçeneğini hizmet tanımına 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. İşlem tetikleyicileri APEX'lerde desteklenmez.
Güncelleme yapılabilir olarak işaretlenmiş bir hizmet, APEX'ler etkinleştirilmeden önce başlarsa APEX'lerin etkinleştirilmesi tamamlanana kadar başlatma işlemi ertelenir.
Sistemi APEX güncellemelerini destekleyecek şekilde 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
veya
<device.mk>:
$(call inherit-product, $(SRC_TARGET_DIR)/product/updatable_apex.mk)
Düzleştirilmiş APEX
Eski cihazlarda, eski çekirdeği APEX'i tam olarak destekleyecek şekilde güncellemek bazen imkansız veya uygulanamaz olabilir. Örneğin, çekirdek CONFIG_BLK_DEV_LOOP=Y
olmadan oluşturulmuş olabilir. Bu, dosya sistemi imajının bir APEX'e monte edilmesi için çok önemlidir.
Düzleştirilmiş APEX, eski bir çekirdeğe sahip cihazlarda etkinleştirilebilen özel olarak oluşturulmuş bir APEX'tir. Birleştirilmiş APEX'teki dosyalar, yerleşik bölümlendirmenin altındaki dizine doğrudan yüklenir. Örneğin, düzleştirilmiş bir APEX'teki lib/libFoo.so
, my.apex
olarak /system/apex/my.apex/lib/libFoo.so
'ye yüklenir.
Düzleştirilmiş bir APEX etkinleştirildiğinde döngü cihazı dahil edilmez. /system/apex/my.apex
dizininin tamamı doğrudan /apex/name@ver
öğesine bağlanır.
İndirilen APEX'ler birleştirilemediği için birleştirilmiş APEX'ler, APEX'lerin güncellenmiş sürümlerini ağdan indirilerek güncellenemez. Birleştirilmiş APEX'ler yalnızca normal bir OTA ile güncellenebilir.
Düzleştirilmiş APEX varsayılan yapılandırmadır. Bu, cihazınızı APEX güncellemelerini destekleyecek şekilde düzeltilmemiş APEX'ler oluşturacak şekilde (yukarıda açıklandığı gibi) açıkça yapılandırmadığınız sürece tüm APEX'ler varsayılan olarak birleştirilir.
Düzleştirilmiş ve birleştirilmemiş APEX'lerin bir cihazda birlikte kullanı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 imzalı APEX'leri gönderirken önemlidir. Önceden imzalanmamış (yani kaynaktan derlenmiş) APEX'ler de düzeltilmemiş olmalıdır ve uygun anahtarlarla imzalanmalıdır. Cihaz, Bir hizmeti APEX ile güncelleme bölümünde açıklandığı gibi updatable_apex.mk
kaynağından devralınmalıdır.
Sıkıştırılmış APEX'ler
Android 12 ve sonraki sürümlerde, güncellenebilir APEX paketlerinin depolama üzerindeki etkisini azaltmak için APEX sıkıştırması bulunur. Bir APEX güncellemesi yüklendikten sonra, önceden yüklenmiş sürümü artık kullanılmasa bile aynı miktarda alanı kaplar. Bu dolu alan kullanılamaz.
APEX sıkıştırması, salt okunur bölümlerde (/system
bölümü gibi) yüksek oranda sıkıştırılmış bir APEX dosyası grubu kullanarak bu depolama alanını en aza indirir. Android
12 ve sonraki sürümler DEFLATE zip sıkıştırma algoritması kullanır.
Sıkıştırma işlemiyle aşağıdakiler için optimizasyon yapılmaz:
Başlatma sırasında çok erken eklenmesi gereken önyükleme APEX'leridir.
Güncellenemeyen APEX'ler. Sıkıştırma yalnızca
/data
bölümünde APEX'in güncellenmiş bir sürümü yüklüyse faydalı olur. Güncellenebilir APEX'lerin tam listesini Modüler Sistem Bileşenleri sayfasında bulabilirsiniz.Dinamik paylaşılan kitaplık APEX'leri.
apexd
, bu tür APEX'lerin her iki sürümünü de (önceden yüklenmiş ve yükseltilmiş) her zaman etkinleştirdiğinden, bunları sıkıştırmak değer sağlamaz.
Sıkıştırılmış APEX dosyası biçimi
Bu, sıkıştırılmış bir APEX dosyasının biçimidir.
Şekil 2. Sıkıştırılmış APEX dosya biçimi
Üst düzeyde, sıkıştırılmış APEX dosyası orijinal Apex dosyasını sıkıştırılmış biçimde 9 olan sıkıştırılmış biçimde ve diğer dosyalar sıkıştırılmamış halde depolanan diğer dosyaları içeren bir zip dosyasıdır.
APEX dosyası dört dosyadan oluşur:
original_apex
: 9 sıkıştırma düzeyiyle azaltılmıştır Bu, orijinal ve sıkıştırılmamış APEX dosyasıdır.apex_manifest.pb
: yalnızca depolanırAndroidManifest.xml
: yalnızca depolanırapex_pubkey
: yalnızca depolanır
apex_manifest.pb
, AndroidManifest.xml
ve apex_pubkey
dosyaları, original_apex
uygulamasındaki ilgili dosyaların kopyalarıdır.
Sıkıştırılmış APEX oluşturma
Sıkıştırılmış APEX, system/apex/tools
adresindeki apex_compression_tool.py
aracı kullanılarak oluşturulabilir.
Derleme sisteminde APEX sıkıştırmasıyla ilgili çeşitli parametreler mevcuttur.
Android.bp
ürününde APEX dosyasının sıkıştırılabilir olup olmadığı compressible
özelliği tarafından kontrol edilir:
apex {
name: "apex.test",
manifest: "apex_manifest.json",
file_contexts: "file_contexts",
compressible: true,
}
PRODUCT_COMPRESSED_APEX
ürün işareti, kaynaktan oluşturulan bir sistem resminin sıkıştırılmış APEX dosyaları içermesi gerekip gerekmediğini kontrol eder.
Yerel denemeler için OVERRIDE_PRODUCT_COMPRESSED_APEX=
değerini true
olarak ayarlayarak bir derlemeyi 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ümlerini birbirinden ayırt etmeyi kolaylaştırır.
Desteklenen sıkıştırma algoritmaları
Android 12 yalnızca deflate zip sıkıştırmayı destekler.
Başlatma 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
dizininde sıkıştırılır. Elde edilen sıkıştırılmış APEX dosyası /data/apex/active
dizinine sabitlenir.
Yukarıda açıklanan sürecin bir örneği olarak aşağıdaki örneği düşünün.
/system/apex/com.android.foo.capex
öğesini versionCode 37 ile etkinleştirilen bir sıkıştırılmış APEX olarak düşünün.
/system/apex/com.android.foo.capex
içindekioriginal_apex
dosyasının sıkıştırması/data/apex/decompressed/com.android.foo@37.apex
içinde çözü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.- Doğrulama kontrolleri, geçerliliğinin sağlanması için
/data/apex/decompressed/com.android.foo@37.apex
tarihinde gerçekleştirilir:apexd
,/system/apex/com.android.foo.capex
içinde paketlenenle aynı olduğunu doğrulamak için/data/apex/decompressed/com.android.foo@37.apex
içinde paketlenen ortak anahtarı kontrol eder. /data/apex/decompressed/com.android.foo@37.apex
dosyası,/data/apex/active/com.android.foo@37.apex
dizinine sabitlenmiştir.- Sıkıştırılmamış APEX dosyaları için normal etkinleştirme 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 yayını ve uygulaması üzerinde etkileri vardır. OTA güncellemesi, cihazda etkin olandan daha yüksek bir sürüm seviyesine sahip sıkıştırılmış bir APEX dosyası içerebileceğinden, OTA güncellemesinin uygulanması için cihaz yeniden başlatılmadan önce belirli bir miktarda boş alan ayrılması gerekir.
apexd
, OTA sistemini desteklemek için şu iki bağlayıcı API'yi kullanıma sunar:
calculateSizeForCompressedApex
: Bir OTA paketindeki APEX dosyalarının sıkıştırılmış sürümünü açmak için gereken boyutu hesaplar. Bu yöntem, OTA indirilmeden önce cihazda yeterli alan olup olmadığını doğrulamak için kullanılabilir.reserveSpaceForCompressedApex
: OTA paketindeki sıkıştırılmış APEX dosyalarının sıkıştırmasını açmak içinapexd
tarafından gelecekte kullanılmak üzere diskte yer ayırır.
A/B OTA güncellemesi söz konusu olduğunda apexd
, yükleme sonrası OTA rutini kapsamında arka planda sıkıştırma işlemini gerçekleştirmeye çalışır. Sıkıştırma açma işlemi başarısız olursa apexd
, OTA güncellemesini uygulayan önyükleme sırasında sıkıştırma açma işlemini gerçekleştirir.
APEX geliştirirken dikkate alınan alternatifler
AOSP'nin APEX dosya biçimini tasarlarken değerlendirdiği bazı seçenekler ve bunların neden dahil edildiği veya hariç tutulduğu aşağıda açıklanmıştır.
Normal paket yönetim sistemleri
Linux dağıtımları; dpkg
ve rpm
gibi güçlü, olgun ve sağlam paket yönetimi sistemlerine sahiptir. Ancak kurulumdan sonra paketleri koruyamayacakları için APEX için benimsenmemiştir. Doğrulama yalnızca paketler yüklenirken gerçekleştirilir.
Saldırganlar, yüklü paketlerin bütünlüğünü fark etmeden bozulabilir. Bu, Android için regresyondur. Bu regresyonda, tüm sistem bileşenleri, her G/Ç için bütünlüğü dm-verity ile korunan dosya sistemlerinde depolanır. Sistem bileşenlerinde yapılan tüm değişiklikler yasaklanmalı veya cihazın güvenliği ihlal edildiğinde cihazın başlatılmasını reddedebileceği şekilde algılanabilir olmalıdır.
Bütünlük için dm-crypt
APEX kapsayıcısındaki dosyalar, dm-verity ile korunan yerleşik bölümlerden (ör. /system
bölümü) alınır. Bu bölümler monte edildikten sonra bile dosyalarda herhangi bir değişiklik yapılması yasaktır. Dosyalara aynı düzeyde güvenlik sağlamak için APEX'teki tüm dosyalar, karma ağacı ve vbmeta tanımlayıcısı ile eşleştirilen bir dosya sistemi görüntüsünde depolanı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.
/data
bölümü, dm-crypt gibi şifreleme katmanlarıyla da korunur. Bu, bozulmaya karşı bir düzeyde koruma sağlar ancak birincil amacı bütünlük değil gizliliktir. Bir saldırgan /data
bölümüne eriştiğinde başka bir koruma olamaz. Bu durum, tüm sistem bileşenlerinin /system
bölümünde bulunduğu duruma kıyasla yine bir gerilemedir.
Bir APEX dosyasındaki karma ağacı, dm-verity ile birlikte aynı düzeyde içerik koruması sağlar.
/system konumundan /apex konumuna yönlendirme yolları
APEX'te paketlenmiş sistem bileşeni dosyalarına /apex/<name>/lib/libfoo.so
gibi yeni yollar üzerinden erişilebilir. Dosyalar, /system
bölümündeyken /system/lib/libfoo.so
gibi yollardan erişilebiliyordu. APEX dosyasının istemcisi (diğer APEX dosyaları veya platform) yeni yolları kullanmalıdır. Yol değişikliği nedeniyle mevcut kodu güncellemeniz gerekebilir.
Yol değişikliğini önlemenin bir yolu, APEX dosyasındaki dosya içeriklerini /system
bölümüne yerleştirmek olsa da Android ekibi, yer paylaşımlı dosyaların sayısı (muhtemelen art arda yığılması bile) arttığı için performansı /system
bölümüne yerleştirmemeye karar verdi.
Diğer bir seçenek de open
, stat
ve readlink
gibi dosya erişimi işlevlerini ele geçirmekti. Böylece /system
ile başlayan yollar, /apex
altındaki ilgili yollarına yönlendiriliyordu. Yolları kabul eden tüm işlevlerin değiştirilmesi mümkün olmadığından Android ekibi bu seçeneği iptal etmiştir.
Örneğin, bazı uygulamalar işlevleri uygulayan Bionic'i statik olarak bağlar.
Bu tür durumlarda, söz konusu uygulamalar yönlendirilmez.