APEX Dosya Biçimi

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.

APEX dosya biçimi

Ş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.

  1. Bir APEX dosyası, bir paket yükleyici uygulaması, ADB veya başka bir kaynak aracılığıyla indirilir.
  2. 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.
  3. APEX yöneticisi APEX dosyasını doğrular.
  4. 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.
  5. Yükleme isteğinde bulunan kişi, başarılı paket doğrulamasının ardından bir yayın alır.
  6. Kuruluma devam etmek için sistem yeniden başlatılmalıdır.
  7. Bir sonraki önyüklemede, APEX yöneticisi başlar, dahili veritabanını okur ve listelenen her APEX dosyası için aşağıdakileri yapar:

    1. APEX dosyasını doğrular.
    2. APEX dosyasından bir geri döngü aygıtı oluşturur.
    3. Geri döngü cihazının üstünde bir cihaz eşleyici blok cihazı oluşturur.
    4. 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 pair
openssl genrsa -out foo.pem 4096

# extract the public key from the key pair
avbtool extract_public_key --key foo.pem --output foo.avbpubkey

# in Android.bp
apex_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 olarak build/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:

  1. Bir OEM veya ODM, aygıt sevk edildiğinde /system/apex altında bir APEX'i önceden yükler.
  2. APEX'teki dosyalara /apex/<apex_name>/ yolu üzerinden erişilir.
  3. 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:

  1. 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
    
  2. Güncellenen hizmet için yeni bir .rc dosyası oluşturun. Mevcut hizmeti yeniden tanımlamak için override 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.

Diagram shows the format of a compressed APEX file

Ş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.

  1. /system/apex/com.android.foo.capex içindeki original_apex dosyası, /data/apex/decompressed/com.android.foo@37.apex olarak açılır.
  2. restorecon /data/apex/decompressed/com.android.foo@37.apex doğru bir SELinux etiketine sahip olduğunu doğrulamak için gerçekleştirilir.
  3. 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.
  4. /data/apex/decompressed/com.android.foo@37.apex dosyası /data/apex/active/com.android.foo@37.apex dizinine sabit bağlantılıdır.
  5. 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çin apexd 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.