Android Pony EXpress (APEX) kapsayıcı formatı Android 10'da tanıtıldı ve alt düzey sistem modülleri için yükleme akışında kullanıldı. Bu format, standart Android uygulama modeline uymayan sistem bileşenlerinin güncellenmesini kolaylaştırır. Bazı örnek bileşenler arasında yerel hizmetler ve kitaplıklar, donanım soyutlama katmanları ( HAL'ler ), çalışma zamanı ( ART ) ve sınıf kitaplıkları yer alır.
"APEX" terimi aynı zamanda bir APEX dosyasına da işaret edebilir.
Arka plan
Android, paket yükleyici uygulamaları (Google Play Store uygulaması gibi) aracılığıyla standart uygulama modeline uyan modüllerin (örneğin hizmetler, etkinlikler) güncellemelerini desteklese de, daha düşük seviyeli 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, uygulamalar hakkındaki bilgilerin merkezi deposudur ve yalnızca önyükleme prosedürünün daha sonraki bir aşamasında hazır hale gelen etkinlik yöneticisinden başlatılabilir.
- APK formatı (özellikle manifest) Android uygulamaları için tasarlanmıştır ve sistem modülleri her zaman uygun değildir.
Tasarım
Bu bölümde APEX dosya formatının üst düzey tasarımı ve APEX dosyalarını yöneten bir hizmet olan APEX yöneticisi açıklanmaktadır.
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 biçimi
Bu bir APEX dosyasının formatıdır.
Şekil 1. APEX dosya formatı
En üst düzeyde, APEX dosyası, dosyaların sıkıştırılmamış olarak 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ı, bir APEX dosyasını tanımlayan paket adını ve sürümünü içerir. Bu, JSON formatında bir ApexManifest
protokol arabelleğidir.
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 olanak tanır. Ö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 bilgi genellikle apex_manifest.json
dosyasında da mevcuttur.
APEX ile ilgilenen 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 bir geridöngü aygıtı aracılığıyla bağlanır. Özellikle karma ağacı ve meta veri bloğu libavb
kütüphanesi kullanılarak oluşturulur. Dosya sistemi verisi ayrıştırılmaz (çünkü görüntünün yerinde takılabilir 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 genel 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 kuralları
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'ler için ayrılmıştır. Herhangi bir şirkete veya cihaza özgü değildir.
-
com.<companyname>.*
- Bir şirkete rezerve edilmiştir. Potansiyel olarak söz konusu şirkete ait birden fazla cihaz tarafından kullanılmaktadır.
-
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ı doğrulamaktan, yüklemekten ve kaldırmaktan sorumlu bağımsız bir yerel işlemdir. Bu işlem başlatılır ve önyükleme sırasının başlarında hazır olur. APEX dosyaları normalde cihaza /system/apex
altında önceden yüklenmiştir. APEX yöneticisi, herhangi bir güncelleme mevcut değilse 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. Paket yöneticisi, dosyanın bir APEX olduğunu anladıktan sonra 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ştirileceğini yansıtacak şekilde güncellenir.
- Kurulum 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 sistemin yeniden başlatılması gerekir.
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 geridöngü aygıtı oluşturur.
- Geridöngü aygıtının üstünde bir aygıt eşleyici blok aygıtı oluşturur.
- Cihaz eşleyici blok cihazı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ındaki bilgileri sorgulaması için bir bağlayıcı hizmet sağlar. Örneğin, diğer sistem bileşenleri, cihazda yüklü olan 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 imzalı zip arşivleri (APK imza şemasını kullanan) olduğundan geçerli APK dosyalarıdır. Bu, APEX dosyalarının APK dosyaları için paket yükleyici uygulaması, imzalama yardımcı programı ve paket yöneticisi gibi altyapıyı kullanmasına olanak tanır.
Bir APEX dosyası 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
oluşur. Bu bilgi, APEX dosyalarının paket yükleyici uygulamaları ve ADB gibi mevcut kanallar aracılığıyla teslim edilmesine olanak tanır.
Desteklenen dosya türleri
APEX formatı şu dosya türlerini destekler:
- Yerel paylaşılan kütüphaneler
- 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üncellenemeyeceği platforma ve dosya türleri için arayüz tanımlarının ne kadar kararlı olduğuna bağlıdır.
İmzalama seçenekleri
APEX dosyaları iki şekilde imzalanır. Öncelikle apex_payload.img
(özellikle apex_payload.img
dosyasına eklenen vbmeta tanımlayıcı) dosyası bir anahtarla imzalanır. Daha sonra 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 ortak anahtar kurulur. APEX yöneticisi, kurulması istenen APEX'leri doğrulamak için ortak anahtarı kullanır. Her APEX'in farklı anahtarlarla imzalanması gerekir ve hem derleme 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'nin üzerinde olduğundan APEX dosyaları doğrudan geri döngü aygıtının üzerine bağlanır.
Yerleşik bir bölümde bir APEX mevcutsa APEX, aynı paket adına ve sürüm kodundan büyük veya eşit olan bir APEX paketi sağlanarak güncellenebilir. Yeni APEX, /data
dosyasında 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ölgede bırakır. Ancak APK'lardan farklı olarak APEX'in yeni yüklenen sürümü yalnızca yeniden başlatmanın ardından etkinleştirilir.
Çekirdek gereksinimleri
Bir Android cihazda APEX ana hat modüllerini desteklemek için aşağıdaki Linux çekirdek özellikleri gereklidir: geridö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 sistem performansı elde etmede geridöngü sürücüsünün ve dm-verity'nin performansı önemlidir.
Desteklenen çekirdek sürümleri
APEX ana hat modülleri, çekirdek sürümleri 4.4 veya üzerini kullanan cihazlarda desteklenir. Android 10 veya üzeri sürümlerle başlatılan yeni cihazların, APEX modüllerini desteklemek için çekirdek sürümü 4.9 veya üzerini kullanması gerekir.
Gerekli çekirdek yamaları
APEX modüllerini desteklemek için gerekli ç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 yapılması şiddetle tavsiye edilir. Aşağıda çekirdek 4.4 sürümü için gerekli bireysel yamaların listesi bulunmaktadır.
- UPSTREAM: döngü: mantıksal blok boyutunu değiştirmek için ioctl ekleyin ( 4.4 )
- BACKPORT: blok/döngü: hw_sectors'ı ayarla ( 4.4 )
- UPSTREAM: döngü: uyumlu ioctl'ye LOOP_SET_BLOCK_SIZE ekleyin ( 4.4 )
- ANDROID: mnt: next_descendent'i düzelt ( 4.4 )
- ANDROID: mnt: remount kölelerin kölelerine yayılmalı ( 4.4 )
- ANDROID: mnt: Yeniden montajı doğru şekilde yay ( 4.4 )
- "ANDROID: dm verity: minimum önceden getirme boyutunu ekle" ifadesini geri alın ( 4.4 )
- UPSTREAM: döngü: ofset veya blok_boyutu 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
şubesinden 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şareti (*) olan öğeler, Android 9 ve daha önceki sürümlerden 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
ayarlanmamalıdır -
loop.max_part
<= 8 olmalıdır
Bir APEX oluşturun
Bu bölümde Android derleme sistemini kullanarak bir APEX'in nasıl oluşturulacağı 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 tipi | APEX'teki konum |
---|---|
Paylaşılan kütüphaneler | /lib ve /lib64 ( x86'da çevrilmiş kol için /lib/arm ) |
Yürütülebilir dosyalar | /bin |
Java kitaplıkları | /javalib |
Önceden oluşturulmuş yapılar | /etc |
Geçişli bağımlılıklar
APEX dosyaları otomatik olarak yerel paylaşılan kütüphanelerin veya yürütülebilir dosyaların geçişli bağımlılıklarını içerir. Örneğin, libFoo
libBar
bağlıysa, native_shared_libs
özelliğinde yalnızca libFoo
listelendiğinde iki kütüphane dahil edilir.
Birden fazla ABI'yi yönetin
Cihazı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 karşılık gelen 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:
- Aygıt yalnızca 32 bit ise, ikili dosyanın yalnızca 32 bit sürümü yüklenir.
- Cihaz yalnızca 64 bit ise ikili dosyanın yalnızca 64 bit sürümü 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'siyle eşleşir. Bu, ikili dosyalar için varsayılandır. -
lib32
: Destekleniyorsa cihazın 32 bit ABI'siyle eşleşir. -
lib64
: Desteklediği cihazın 64 bit ABI'sıyla eşleşir. -
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 de eşleşir. Bunative_shared_libraries
için varsayılandır.
java
, libraries
ve prebuilts
özellikler 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 imzalama
Her APEX'i farklı anahtarlarla imzalayın. Yeni bir anahtar gerektiğinde, genel-özel anahtar çifti oluşturun ve bir apex_key
modülü oluşturun. Anahtarı kullanarak APEX'i imzalamak için key
özelliğini kullanın. Genel anahtar, avb_pubkey
adıyla APEX'e 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 haline gelir. APEX'i imzalamak için kullanılan anahtarın kimliği APEX'e yazılır. Çalışma zamanında apexd
, cihazdaki aynı kimliğe sahip genel anahtarı kullanarak APEX'i doğrular.
APEX imzası
APEX'leri, APK'ları imzaladığınız şekilde imzalayın. APEX'leri iki kez imzalayın; bir kez mini dosya sistemi için ( apex_payload.img
dosyası) ve bir kez de dosyanın tamamı için.
Dosya düzeyinde bir APEX imzalamak için certificate
özelliğini şu üç yoldan biriyle ayarlayın:
- Ayarlanmadı: Hiçbir değer ayarlanmadıysa APEX,
PRODUCT_DEFAULT_DEV_CERTIFICATE
konumunda bulunan sertifikayla imzalanır. Hiçbir bayrak 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 sertifika ile 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)
}
Bir APEX yükleyin
APEX yüklemek için ADB'yi kullanın.
adb install apex_file_name
adb reboot
apex_manifest.json
dosyasında supportsRebootlessUpdate
true
olarak ayarlanmışsa ve şu anda yüklü olan APEX kullanılmıyorsa (örneğin, içerdiği hizmetler durdurulmuşsa), --force-non-staged
bayrağıyla yeniden başlatmaya gerek kalmadan yeni bir APEX yüklenebilir .
adb install --force-non-staged apex_file_name
APEX kullanın
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>
konumunda bağlamayla bağlanır.
İstemciler, APEX'ten dosyaları okumak veya yürütmek için bağlamaya bağlı yolu kullanabilir.
APEX'ler genellikle şu şekilde kullanılır:
- Bir OEM veya ODM, cihaz gönderildiğinde
/system/apex
altına bir APEX'i önceden yükler. - APEX'teki dosyalara
/apex/<apex_name>/
yolu aracılığıyla erişilir. - APEX'in güncellenmiş bir sürümü
/data/apex
yüklendiğinde yol, yeniden başlatmanın ardından yeni APEX'i işaret eder.
Bir hizmeti APEX ile güncelleme
APEX kullanarak bir hizmeti güncellemek için:
Hizmeti sistem bölümünde 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. Eylem tetikleyicileri APEX'lerde desteklenmez.
Güncellenebilir olarak işaretlenen bir hizmet APEX'ler etkinleştirilmeden önce başlatılırsa başlatma, APEX'lerin etkinleştirilmesi tamamlanana kadar ertelenir.
Sistemi APEX güncellemelerini destekleyecek şekilde yapılandırın
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ğin APEX'i tam olarak destekleyecek şekilde güncellenmesi bazen imkansız veya mümkün olmayabilir. Örneğin çekirdek, dosya sistemi görüntüsünün bir APEX içine yerleştirilmesi için çok önemli olan CONFIG_BLK_DEV_LOOP=Y
olmadan oluşturulmuş olabilir.
Düzleştirilmiş APEX, eski çekirdeğe sahip cihazlarda etkinleştirilebilen, özel olarak oluşturulmuş bir APEX'tir. Düzleştirilmiş bir APEX'teki dosyalar doğrudan yerleşik bölümün altındaki bir dizine yüklenir. Örneğin, düzleştirilmiş bir APEX'teki lib/libFoo.so
my.apex
/system/apex/my.apex/lib/libFoo.so
konumuna yüklenir.
Düzleştirilmiş bir APEX'in etkinleştirilmesi döngü cihazını gerektirmez. /system/apex/my.apex
dizininin tamamı doğrudan /apex/name@ver
dizinine bağlanır.
Düzleştirilmiş APEX'ler, indirilen APEX'ler düzleştirilemediğinden, APEX'lerin güncellenmiş sürümleri ağdan 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 üzere 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 (yukarıda açıklandığı gibi).
Düzleştirilmiş ve düzleştirilmemiş APEX'lerin bir cihazda karıştırılması DESTEKLENMEZ. Bir cihazdaki APEX'lerin ya tamamı düzleştirilmemiş ya da tamamı düzleştirilmiş olmalıdır. Bu, özellikle Mainline gibi projeler için önceden imzalanmış APEX önceden oluşturulmuş sürümleri gönderilirken önemlidir. Önceden imzalanmamış (yani kaynaktan oluşturulmuş) APEX'ler de düzleştirilmemeli ve uygun anahtarlarla imzalanmalıdır. Cihaz , Bir hizmeti APEX ile güncelleme bölümünde açıklandığı gibi updatable_apex.mk
miras almalıdır.
Sıkıştırılmış APEX'ler
Android 12 ve sonraki sürümler, güncellenebilir APEX paketlerinin depolama etkisini azaltmak için APEX sıkıştırma özelliğine sahiptir. APEX'e yönelik bir güncelleme yüklendikten sonra, önceden yüklenmiş sürümü artık kullanılmasa da aynı miktarda alanı kaplar. Bu işgal edilen alan kullanılamıyor.
APEX sıkıştırması, salt okunur bölümlerde ( /system
bölümü gibi) yüksek düzeyde sıkıştırılmış APEX dosyaları kümesi kullanarak bu depolama etkisini en aza indirir. Android 12 ve sonraki sürümler DEFLATE zip sıkıştırma algoritmasını kullanır.
Sıkıştırma aşağıdakiler için optimizasyon sağlamaz:
Önyükleme sırasında çok erken monte edilmesi gereken Bootstrap APEX'ler.
Güncellenemeyen APEX'ler. Sıkıştırma yalnızca
/data
bölümüne APEX'in güncellenmiş bir sürümü yüklendiğinde faydalıdır. Güncellenebilir APEX'lerin tam listesi Modüler Sistem Bileşenleri sayfasında mevcuttur.Dinamik paylaşılan kütüphaneler APEX'ler.
apexd
her zaman bu tür APEX'lerin her iki versiyonunu da etkinleştirdiğinden (önceden yüklenmiş ve yükseltilmiş), bunları sıkıştırmak değer katmaz.
Sıkıştırılmış APEX dosya formatı
Bu, sıkıştırılmış bir APEX dosyasının formatıdır.
Şekil 2. Sıkıştırılmış APEX dosya formatı
En üst düzeyde, sıkıştırılmış bir APEX dosyası, orijinal apex dosyasını sönük biçimde, sıkıştırma düzeyi 9 olan ve sıkıştırılmamış olarak saklanan diğer dosyaları içeren bir zip dosyasıdır.
Dört dosya bir APEX dosyasından oluşur:
-
original_apex
: 9 sıkıştırma düzeyiyle 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
karşılık gelen dosyaların kopyalarıdır.
Sıkıştırılmış APEX oluşturun
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 yapı 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 kontrol eder.
Yerel denemeler için OVERRIDE_PRODUCT_COMPRESSED_APEX=
değerini 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ştirin
Sıkıştırılmış bir APEX etkinleştirilmeden önce, içindeki original_apex
dosyasının sıkıştırması /data/apex/decompressed
dizinine açılır. Ortaya çıkan sıkıştırması açılmış APEX dosyası /data/apex/active
dizinine sabit olarak bağlıdır.
Yukarıda açıklanan sürecin bir örneği olarak aşağıdaki örneği düşünün.
/system/apex/com.android.foo.capex
versionCode 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ının sıkıştırması/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
üzerinde 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 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 dağıtımı ve uygulaması üzerinde etkileri vardır. Bir OTA güncellemesi, cihazda etkin olandan daha yüksek sürüm seviyesine sahip sıkıştırılmış bir APEX dosyası içerebileceğinden, bir OTA güncellemesini uygulamak için 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 kullanıma sunar:
-
calculateSizeForCompressedApex
- OTA paketindeki APEX dosyalarının sıkıştırmasını açmak için gereken boyutu hesaplar. Bu, bir OTA indirilmeden önce 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ın sıkıştırmasını açmak içinapexd
tarafından gelecekte kullanılmak üzere diskte alan ayırır.
A/B OTA güncellemesi durumunda apexd
, kurulum sonrası OTA rutininin bir parçası olarak arka planda sıkıştırmayı açmayı dener. Sıkıştırmayı açma işlemi başarısız olursa apexd
, OTA güncellemesini uygulayan önyükleme sırasında sıkıştırmayı açma işlemini gerçekleştirir.
APEX geliştirilirken dikkate alınan alternatifler
APEX dosya formatını tasarlarken AOSP'nin dikkate aldığı bazı seçenekleri ve bunların neden dahil edildiğini veya hariç tutulduğunu burada bulabilirsiniz.
Düzenli paket yönetim sistemleri
Linux dağıtımları dpkg
ve rpm
gibi güçlü, olgun ve sağlam paket yönetim sistemlerine sahiptir. Ancak kurulumdan sonra paketleri koruyamadıkları için APEX'e uyarlanmadılar. Doğrulama yalnızca paketler yüklenirken gerçekleştirilir. Saldırganlar, kurulu paketlerin bütünlüğünü fark edilmeden bozabilirler. Bu, tüm sistem bileşenlerinin, her G/Ç için bütünlüğü dm-verity tarafından korunan salt okunur dosya sistemlerinde depolandığı Android için bir gerilemedir. Sistem bileşenlerine yapılacak herhangi bir müdahale ya yasaklanmalı ya da aygıtın tehlikeye atılması durumunda önyüklemeyi reddedebilmesi için tespit edilebilir olmalıdır.
bütünlük için dm-crypt
APEX kapsayıcısındaki dosyalar, dm-verity tarafından korunan yerleşik bölümlerden (örneğin, /system
bölümü) gelir; burada bölümler bağlandıktan 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ıyla eşleştirilen bir dosya sistemi görüntüsünde saklanır. Dm-verity olmadan, /data
bölümündeki bir APEX, doğrulanıp yüklendikten sonra yapılan istenmeyen değişikliklere karşı savunmasızdır.
Aslında /data
bölümü aynı zamanda dm-crypt gibi şifreleme katmanları tarafından da korunmaktadır. Bu, tahrifata karşı bir miktar koruma sağlasa da, asıl 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 her sistem bileşeninin /system
bölümünde olmasıyla karşılaştırıldığında bir gerilemedir. Bir APEX dosyasının içindeki karma ağacı, dm-verity ile birlikte aynı düzeyde içerik koruması sağlar.
Yolları /system'den /apex'e yönlendirin
APEX'te paketlenmiş sistem bileşeni dosyalarına /apex/<name>/lib/libfoo.so
gibi yeni yollardan erişilebilir. Dosyalar /system
bölümünün parçası olduğunda, bunlara /system/lib/libfoo.so
gibi yollardan erişilebilir. 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ğini önlemenin bir yolu, bir APEX dosyasındaki dosya içeriğini /system
bölümüne yerleştirmek olsa da, Android ekibi, üst üste bindirilen dosya sayısı nedeniyle performansı etkileyebileceğinden, /system
bölümündeki dosyaları üst üste bindirmemeye karar verdi ( hatta muhtemelen birbiri ardına istiflenmiş) arttı.
Diğer bir seçenek ise 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 yollara yeniden yönlendirildi. Android ekibi, yolları kabul eden tüm işlevleri değiştirmek mümkün olmadığından bu seçeneği göz ardı etti. Örneğin, bazı uygulamalar, işlevleri uygulayan Bionic'i statik olarak bağlar. Bu gibi durumlarda bu uygulamalar yönlendirilmez.