تنسيق ملف APEX

تم تقديم تنسيق حاوية Android Pony EXpress (APEX) في Android 10 ويتم استخدامه في تدفق التثبيت لوحدات النظام ذات المستوى الأدنى. يسهل هذا التنسيق تحديثات مكونات النظام التي لا تتناسب مع نموذج تطبيق Android القياسي. بعض مكونات سبيل المثال هي خدمات الأم والمكتبات، وطبقات تجريد الأجهزة ( طبقة تجريد )، وقت التشغيل ( ART )، ومكتبات فئة.

يمكن أن يشير المصطلح "APEX" أيضًا إلى ملف APEX.

خلفية

على الرغم من أن Android يدعم تحديثات الوحدات النمطية التي تتلاءم مع نموذج التطبيق القياسي (على سبيل المثال ، الخدمات والأنشطة) عبر تطبيقات مثبت الحزمة (مثل تطبيق متجر Google Play) ، فإن استخدام نموذج مشابه لمكونات نظام التشغيل منخفضة المستوى له العيوب التالية:

  • لا يمكن استخدام الوحدات المستندة إلى APK في وقت مبكر من تسلسل التمهيد. مدير الحزم هو المستودع المركزي للمعلومات حول التطبيقات ولا يمكن تشغيله إلا من مدير النشاط ، والذي يصبح جاهزًا في مرحلة لاحقة من إجراء التمهيد.
  • تم تصميم تنسيق APK (خاصة البيان) لتطبيقات Android ولا تكون وحدات النظام مناسبة دائمًا.

تصميم

يصف هذا القسم التصميم عالي المستوى لتنسيق ملف APEX ومدير APEX ، وهي خدمة تدير ملفات APEX.

لمزيد من المعلومات حول لماذا تم اختيار هذا التصميم لAPEX، انظر البدائل في الاعتبار عند تطوير APEX .

شكل APEX

هذا هو تنسيق ملف APEX.

تنسيق ملف APEX

تنسيق ملف الشكل 1. APEX

في المستوى الأعلى ، ملف APEX هو ملف مضغوط يتم فيه تخزين الملفات غير المضغوطة والموجودة في حدود 4 كيلوبايت.

الملفات الأربعة في ملف APEX هي:

  • apex_manifest.json
  • AndroidManifest.xml
  • apex_payload.img
  • apex_pubkey

و apex_manifest.json يحتوي ملف اسم الحزمة والإصدار، والتي تحدد ملف APEX.

و AndroidManifest.xml الملف يسمح الملف APEX إلى استخدام الأدوات ذات الصلة APK والبنية التحتية مثل ADB، PackageManager، وتطبيقات حزمة المثبت (مثل متجر Play). على سبيل المثال، يمكن للملف APEX استخدام أداة القائمة مثل aapt لتفقد الفوقية الأساسي من الملف. يحتوي الملف على اسم الحزمة ومعلومات الإصدار. هذه المعلومات بشكل عام باللغات apex_manifest.json .

apex_manifest.json يوصى على AndroidManifest.xml لرمز والأنظمة التي تتعامل مع APEX الجديد. AndroidManifest.xml قد تحتوي على معلومات استهداف الإضافية التي يمكن استخدامها من قبل أدوات النشر التطبيق الحالي.

apex_payload.img هو صورة نظام ext4 ملف تدعمها DM-حقيقة. يتم تثبيت الصورة في وقت التشغيل عبر جهاز استرجاع. على وجه التحديد، يتم إنشاء شجرة التجزئة وكتلة ميتاداتا باستخدام libavb المكتبة. لم يتم تحليل حمولة نظام الملفات (لأن الصورة يجب أن تكون قابلة للتركيب في مكانها). تدرج الملفات العادية داخل apex_payload.img الملف.

apex_pubkey هو المفتاح العمومي المستخدمة للتوقيع على صورة نظام الملفات. في وقت التشغيل ، يضمن هذا المفتاح أن يتم توقيع APEX الذي تم تنزيله بنفس الكيان الذي يوقع نفس APEX في الأقسام المضمنة.

مدير APEX

مدير APEX (أو apexd ) هي بذاتها عملية الأم المسؤولة عن التحقق من تثبيت وإلغاء تثبيت ملفات APEX. تم إطلاق هذه العملية وهي جاهزة في وقت مبكر من تسلسل التمهيد. وعادة مثبتة مسبقا ملفات APEX على الجهاز تحت /system/apex . يتم تعيين مدير APEX افتراضيًا لاستخدام هذه الحزم في حالة عدم توفر تحديثات.

تسلسل التحديث من APEX يستخدم الطبقة PackageManager وعلى النحو التالي.

  1. يتم تنزيل ملف APEX عبر تطبيق مثبت الحزمة أو ADB أو أي مصدر آخر.
  2. يبدأ مدير الحزم إجراء التثبيت. عند التعرف على أن الملف هو APEX ، يقوم مدير الحزم بنقل التحكم إلى مدير APEX.
  3. يتحقق مدير APEX من ملف APEX.
  4. إذا تم التحقق من ملف APEX ، يتم تحديث قاعدة البيانات الداخلية لمدير APEX لتعكس تنشيط ملف APEX عند التمهيد التالي.
  5. يتلقى طالب التثبيت بثًا عند التحقق من الحزمة بنجاح.
  6. لمتابعة التثبيت ، يجب إعادة تشغيل النظام.
  7. في التمهيد التالي ، يبدأ مدير APEX ، ويقرأ قاعدة البيانات الداخلية ، ويقوم بما يلي لكل ملف APEX مدرج:

    1. يتحقق من ملف APEX.
    2. ينشئ جهاز استرجاع من ملف APEX.
    3. ينشئ جهاز حظر مخطط الجهاز أعلى جهاز الاسترجاع.
    4. يتصاعد الجهاز كتلة مخطط الجهاز على مسار فريد (على سبيل المثال، /apex/ name @ ver ).

عندما يتم تحميل جميع ملفات APEX المدرجة في قاعدة البيانات الداخلية ، يوفر مدير APEX خدمة ربط لمكونات النظام الأخرى للاستعلام عن معلومات حول ملفات APEX المثبتة. على سبيل المثال ، يمكن لمكونات النظام الأخرى الاستعلام عن قائمة ملفات APEX المثبتة في الجهاز أو الاستعلام عن المسار الدقيق حيث يتم تثبيت APEX معين ، بحيث يمكن الوصول إلى الملفات.

ملفات APEX هي ملفات APK

ملفات APEX هي ملفات APK صالحة لأنهم قعت البريدي المحفوظات (باستخدام نظام التوقيع APK) التي تحتوي على AndroidManifest.xml الملف. يتيح ذلك لملفات APEX استخدام البنية الأساسية لملفات APK ، مثل تطبيق مثبت الحزمة ، وأداة التوقيع ، ومدير الحزم.

و AndroidManifest.xml ملف داخل ملف APEX هو الحد الأدنى، ويتألف من حزمة name ، versionCode ، واختياري targetSdkVersion ، minSdkVersion ، و maxSdkVersion لالحبيبات غرامة المستهدفة. تسمح هذه المعلومات بتسليم ملفات APEX عبر القنوات الحالية مثل تطبيقات مثبت الحزم و ADB.

أنواع الملفات المدعومة

يدعم تنسيق APEX أنواع الملفات التالية:

  • أصلية مشتركة libs
  • الملفات التنفيذية الأصلية
  • ملفات JAR
  • ملفات البيانات
  • ملفات التكوين

هذا لا يعني أن APEX يمكنه تحديث جميع أنواع الملفات هذه. تعتمد إمكانية تحديث نوع الملف على النظام الأساسي ومدى استقرار تعريفات الواجهات لأنواع الملفات.

التوقيع

يتم توقيع ملفات APEX بطريقتين. أولا، apex_payload.img (على وجه التحديد، واصف vbmeta إلحاق apex_payload.img ) يتم توقيع الملف مع مفتاح. ثم، يتم التوقيع على APEX بأكمله باستخدام V3 APK مخطط توقيع . يتم استخدام مفتاحين مختلفين في هذه العملية.

على جانب الجهاز ، يتم تثبيت مفتاح عام يتوافق مع المفتاح الخاص المستخدم لتوقيع واصف vbmeta. يستخدم مدير APEX المفتاح العام للتحقق من APEXes المطلوب تثبيتها. يجب توقيع كل APEX بمفاتيح مختلفة ويتم فرضها في وقت الإنشاء ووقت التشغيل.

APEX في أقسام مدمجة

ملفات APEX يمكن أن يكون موجودا في المدمج في أقسام مثل /system . القسم بالفعل فوق dm-verity ، لذلك يتم تحميل ملفات APEX مباشرة فوق جهاز الاسترجاع.

إذا كان APEX موجودًا في قسم مضمن ، فيمكن تحديث APEX من خلال توفير حزمة APEX بنفس اسم الحزمة وأكبر من رمز الإصدار أو مساوٍ له. يتم تخزين APEX الجديد في /data و، على غرار ملفات APK لل، النسخة الظلال المثبتة حديثا النسخة الموجودة بالفعل في القسم المضمنة. ولكن على عكس ملفات APK ، لا يتم تنشيط الإصدار المثبت حديثًا من APEX إلا ​​بعد إعادة التشغيل.

متطلبات Kernel

لدعم وحدات APEX mainline على جهاز Android ، يلزم توفر ميزات Linux kernel التالية: برنامج تشغيل الاسترجاع و dm-verity. يقوم برنامج تشغيل الاسترجاع بتثبيت صورة نظام الملفات في وحدة APEX ويتحقق dm-verity من وحدة APEX.

يعد أداء برنامج تشغيل الاسترجاع و dm-verity مهمين في تحقيق أداء جيد للنظام عند استخدام وحدات APEX.

إصدارات kernel المدعومة

يتم دعم وحدات APEX الرئيسية على الأجهزة التي تستخدم إصدارات kernel 4.4 أو أعلى. يجب أن تستخدم الأجهزة الجديدة التي تعمل بنظام Android 10 أو أعلى إصدار kernel 4.9 أو أعلى لدعم وحدات APEX.

تصحيحات النواة المطلوبة

يتم تضمين تصحيحات kernel المطلوبة لدعم وحدات APEX في شجرة Android الشائعة. للحصول على التصحيحات لدعم APEX ، استخدم أحدث إصدار من شجرة Android الشائعة.

إصدار Kernel 4.4.2

هذا الإصدار مدعوم فقط للأجهزة التي تمت ترقيتها من Android 9 إلى Android 10 وتريد دعم وحدات APEX. للحصول على بقع المطلوبة، وأسفل دمج من android-4.4 ينصح بشدة الفرع. فيما يلي قائمة بالتصحيحات الفردية المطلوبة للإصدار 4.4 من kernel.

  • UPSTREAM: حلقة: إضافة IOCTL لتغيير منطقي حجم كتلة ( 4.4 )
  • BACKPORT: كتلة / حلقة: مجموعة hw_sectors ( 4.4 )
  • UPSTREAM: حلقة: إضافة LOOP_SET_BLOCK_SIZE في COMPAT IOCTL ( 4.4 )
  • ANDROID: كزاز: فيكس next_descendent ( 4.4 )
  • ANDROID: كزاز: الفرس البديل يجب نشر إلى العبيد من العبيد ( 4.4 )
  • ANDROID: كزاز: نشر بإعادة تحميل بشكل صحيح ( 4.4 )
  • تعود "ANDROID: DM حقيقة: إضافة الحد الأدنى لحجم الجلب المسبق" ( 4.4 )
  • UPSTREAM: حلقة: انخفاض مخابئ إذا تعويض أو يتم تغيير block_size ( 4.4 )

إصدارات Kernel 4.9 / 4.14 / 4.19

للحصول على بقع اللازمة لإصدارات نواة 4.9 / 4.14 / 4.19، بانخفاض دمج من android-common فرع.

خيارات تكوين النواة المطلوبة

توضح القائمة التالية متطلبات التكوين الأساسية لدعم وحدات APEX التي تم تقديمها في Android 10. العناصر التي تحمل علامة النجمة (*) هي متطلبات حالية من Android 9 وأقل.

(*) 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

متطلبات معلمة سطر أوامر Kernel

لدعم APEX ، تأكد من أن معلمات سطر أوامر kernel تفي بالمتطلبات التالية:

  • loop.max_loop يجب أن لا يتم تعيين
  • loop.max_part يجب أن يكون <= 8

بناء APEX

يصف هذا القسم كيفية إنشاء APEX باستخدام نظام إنشاء Android. وفيما يلي مثال على Android.bp لAPEX اسمه apex.test .

apex {
    name: "apex.test",
    manifest: "apex_manifest.json",
    file_contexts: "file_contexts",
    // libc.so and libcutils.so are included in the apex
    native_shared_libs: ["libc", "libcutils"],
    binaries: ["vold"],
    java_libs: ["core-all"],
    prebuilts: ["my_prebuilt"],
    compile_multilib: "both",
    key: "apex.test.key",
    certificate: "platform",
}

apex_manifest.json سبيل المثال:

{
  "name": "com.android.example.apex",
  "version": 1
}

file_contexts سبيل المثال:

(/.*)?           u:object_r:system_file:s0
/sub(/.*)?       u:object_r:sub_file:s0
/sub/file3       u:object_r:file3_file:s0

أنواع الملفات والمواقع في APEX

نوع الملف الموقع في APEX
مكتبات مشتركة /lib و /lib64 ( /lib/arm للترجمة ذراع في x86) و
الملفات القابلة للتنفيذ /bin
مكتبات جافا /javalib
التجهيز المسبق /etc

التبعيات المتعدية

تتضمن ملفات APEX تلقائيًا تبعيات متعدية من libs أو الملفات التنفيذية المشتركة الأصلية. على سبيل المثال، إذا libFoo يعتمد على libBar ، يتم تضمين يبس اثنين فقط عندما libFoo تم سرده في native_shared_libs الممتلكات.

التعامل مع العديد من ABIs

تثبيت native_shared_libs الملكية لكل من واجهات تطبيق ثنائي الابتدائية والثانوية (أبيس) للجهاز. إذا كان APEX يستهدف أجهزة بها ABI واحد (أي 32 بت فقط أو 64 بت فقط) ، يتم تثبيت المكتبات التي تحتوي على ABI المقابل فقط.

تثبيت binaries الملكية إلا للABI الأساسي للجهاز كما هو موضح أدناه:

  • إذا كان الجهاز 32 بت فقط ، يتم تثبيت متغير 32 بت فقط من الثنائي.
  • إذا كان الجهاز 64 بت فقط ، فسيتم تثبيت الإصدار 64 بت فقط من البرنامج الثنائي.

لإضافة ضبط الحبيبات غرامة على أبيس من المكتبات المحلية والثنائيات، استخدم multilib.[first|lib32|lib64|prefer32|both].[native_shared_libs|binaries] خصائص.

  • first : مباريات لABI الأساسي للجهاز. هذا هو الإعداد الافتراضي للثنائيات.
  • lib32 : مباريات 32 بت ABI للجهاز، إذا كان معتمدا.
  • lib64 : مباريات 64 بت ABI للجهاز، فإنه يؤيد.
  • prefer32 : مباريات 32 بت ABI للجهاز، إذا كان معتمدا. إذا كان 32 بت ABI غير مدعوم ، يتطابق مع 64 بت ABI.
  • both : مباريات كلا أبيس. هذا هو الافتراضي ل native_shared_libraries .

و java ، libraries ، و prebuilts الخصائص هي ABI-الملحد.

هذا المثال لجهاز يدعم 32/64 ولا يفضل 32:

apex {
    // other properties are omitted
    native_shared_libs: ["libFoo"], // installed for 32 and 64
    binaries: ["exec1"], // installed for 64, but not for 32
    multilib: {
        first: {
            native_shared_libs: ["libBar"], // installed for 64, but not for 32
            binaries: ["exec2"], // same as binaries without multilib.first
        },
        both: {
            native_shared_libs: ["libBaz"], // same as native_shared_libs without multilib
            binaries: ["exec3"], // installed for 32 and 64
        },
        prefer32: {
            native_shared_libs: ["libX"], // installed for 32, but not for 64
        },
        lib64: {
            native_shared_libs: ["libY"], // installed for 64, but not for 32
        },
    },
}

توقيع vbmeta

قم بتوقيع كل APEX بمفاتيح مختلفة. عندما يطلب مفتاح جديد، إنشاء زوج مفتاح القطاعين العام والخاص وتقديم apex_key حدة. استخدام key الملكية للتوقيع على APEX باستخدام مفتاح. يتم تلقائيا تضمين المفتاح العمومي في APEX مع اسم avb_pubkey .

# 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",
}

في المثال أعلاه، اسم المفتاح العمومي ( foo ) يصبح معرف مفتاح. يتم كتابة معرف المفتاح المستخدم لتوقيع APEX في APEX. في وقت التشغيل، apexd يتحقق APEX باستخدام المفتاح العمومي مع نفس الرقم في الجهاز.

توقيع ZIP

قم بتوقيع APEXes بنفس طريقة توقيعك على ملفات APK. توقيع APEXes مرتين ؛ مرة واحدة لنظام الملفات مصغرة ( apex_payload.img الملف) ومرة واحدة للملف بأكمله.

التوقيع على APEX على مستوى الملف، تعيين certificate الملكية في واحدة من هذه الطرق الثلاث:

  • لم يتم تغيير: إذا تم تعيين أية قيمة، توقيع APEX مع شهادة الموجود في PRODUCT_DEFAULT_DEV_CERTIFICATE . إذا تم تعيين أي العلم، والتخلف عن طريق build/target/product/security/testkey .
  • <name> : يتم توقيع APEX مع <name> شهادة في نفس الدليل PRODUCT_DEFAULT_DEV_CERTIFICATE .
  • :<name> : يتم توقيع APEX مع الشهادة التي تم تعريفه من قبل وحدة سونغ اسمه <name> . يمكن تعريف وحدة الشهادة على النحو التالي.
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

لتثبيت APEX ، استخدم ADB.

adb install apex_file_name
adb reboot

باستخدام APEX

بعد إعادة التشغيل، هي التي شنت على APEX في /apex/<apex_name>@<version> الدليل. يمكن تركيب إصدارات متعددة من نفس APEX في نفس الوقت. بين جبل مسارات، واحد الذي يتوافق مع أحدث نسخة لإلزام محمولة في /apex/<apex_name> .

يمكن للعملاء استخدام مسار الربط لقراءة أو تنفيذ الملفات من APEX.

يتم استخدام APEXes عادةً على النحو التالي:

  1. وOEM ODM أو تحميلها مسبقا على APEX تحت /system/apex عند شحن الجهاز.
  2. يتم الوصول إلى الملفات في APEX عبر /apex/<apex_name>/ المسار.
  3. عند تثبيت نسخة محدثة من APEX في /data/apex ، ونقاط المسار إلى APEX الجديد بعد إعادة التشغيل.

تحديث الخدمة مع APEX

لتحديث خدمة باستخدام APEX:

  1. قم بتمييز الخدمة في قسم النظام على أنها قابلة للتحديث. إضافة خيار updatable إلى تعريف الخدمة.

    /system/etc/init/myservice.rc:
    
    service myservice /system/bin/myservice
        class core
        user system
        ...
        updatable
    
  2. إنشاء جديد .rc ملف الخدمة التي تم تحديثها. استخدام override الخيار لإعادة الخدمة الحالية.

    /apex/my.apex@1/etc/init.rc:
    
    service myservice /apex/my.apex@1/bin/myservice
        class core
        user system
        ...
        override
    

يمكن تعريف تعريفات الخدمة فقط في .rc ملف من APEX. مشغلات الإجراءات غير مدعومة في APEXes.

إذا بدأت إحدى الخدمات التي تم وضع علامة عليها على أنها قابلة للتحديث قبل تنشيط APEXes ، فسيتم تأخير البدء حتى يكتمل تنشيط APEXes.

تكوين النظام لدعم تحديثات APEX

تعيين الخاصية النظام التالية إلى true لدعم تحديثات ملف APEX.

<device.mk>:

PRODUCT_PROPERTY_OVERRIDES += ro.apex.updatable=true

BoardConfig.mk:
TARGET_FLATTEN_APEX := false

أو فقط

<device.mk>:

$(call inherit-product, $(SRC_TARGET_DIR)/product/updatable_apex.mk)

بالارض APEX

بالنسبة للأجهزة القديمة ، في بعض الأحيان يكون من المستحيل أو غير المجدي تحديث النواة القديمة لدعم APEX بشكل كامل. على سبيل المثال، قد تم بناء نواة دون CONFIG_BLK_DEV_LOOP=Y ، وهو أمر حاسم لتركيب صورة نظام الملفات داخل APEX.

APEX المسطح عبارة عن APEX مبني خصيصًا ويمكن تنشيطه على الأجهزة ذات النواة القديمة. يتم تثبيت الملفات الموجودة في APEX المسطح مباشرة إلى دليل أسفل القسم المدمج. على سبيل المثال، lib/libFoo.so في دكت APEX my.apex تثبيت ل /system/apex/my.apex/lib/libFoo.so .

لا يتضمن تنشيط APEX المسطح جهاز الحلقة. الدليل بالكامل /system/apex/my.apex ومباشرة ربط محمولة ل /apex/name@ver .

لا يمكن تحديث واجهات APEX المسطحة عن طريق تنزيل إصدارات محدثة من APEXes من الشبكة لأنه لا يمكن تسوية APEXes التي تم تنزيلها. لا يمكن تحديث أجهزة APEX المسطحة إلا عبر OTA العادي.

APEX المسطح هو التكوين الافتراضي. هذا يعني أن جميع أجهزة APEX يتم تسويتها افتراضيًا إلا إذا قمت بتكوين جهازك بشكل صريح لإنشاء واجهات APEX غير مسطحة لدعم تحديثات APEX (كما هو موضح أعلاه).

لا يتم دعم الخلط بين أجهزة APEX المسطحة وغير المسطحة في الجهاز. يجب أن تكون أجهزة APEX في الجهاز إما غير مسطحة أو كلها مسطحة. هذا مهم بشكل خاص عند شحن أعمدة APEX مسبقة التوقيع لمشاريع مثل Mainline. يجب أيضًا أن تكون APEX التي لم يتم تعيينها مسبقًا (أي التي تم إنشاؤها من المصدر) غير مسطحة وموقعة بالمفاتيح المناسبة. يجب أن ترث الجهاز من updatable_apex.mk كما هو موضح في تحديث خدمة مع APEX .

أبكس مضغوط

يتميز نظام Android 12 والإصدارات الأحدث بضغط APEX لتقليل تأثير التخزين لحزم APEX القابلة للتحديث. بعد تثبيت تحديث لـ APEX ، على الرغم من عدم استخدام نسخته المثبتة مسبقًا ، إلا أنها لا تزال تشغل نفس القدر من المساحة. تلك المساحة المشغولة لا تزال غير متوفرة.

ضغط APEX يقلل من هذا التأثير التخزين باستخدام مجموعة مضغوط للغاية من الملفات APEX على أقسام للقراءة فقط (مثل /system التقسيم). يستخدم Android 12 والإصدارات الأحدث خوارزمية ضغط DEFLATE.

لا يوفر الضغط تحسينًا لما يلي:

  • Bootstrap APEXes المطلوب تثبيتها مبكرًا في تسلسل التمهيد.

  • APEXes غير قابلة للتحديث. ضغط هو مفيد فقط إذا تم تثبيت إصدار محدث من APEX على /data التقسيم. قائمة كاملة والحصان قابلة للتحديث متوفرة على وحدات مكونات النظام الصفحة.

  • ديناميكية libs المشتركة APEXes. منذ apexd دائما ينشط كلا الإصدارين من هذا القبيل والحصان (مثبتة مسبقا وترقية)، ضغط عليها لا يضيف قيمة.

تنسيق ملف APEX المضغوط

هذا هو تنسيق ملف APEX المضغوط.

Diagram shows the format of a compressed APEX file

شكل ملف مضغوط الشكل 2. APEX

في المستوى الأعلى ، ملف APEX المضغوط هو ملف مضغوط يحتوي على ملف القمة الأصلي في شكل مفرغ من الهواء بمستوى ضغط 9 ، ومع ملفات أخرى مخزنة غير مضغوطة.

تتألف أربعة ملفات من ملف APEX:

  • original_apex : مفرغة من الهواء مع مستوى ضغط من 9 هذا هو الأصل، غير مضغوط ملف APEX .
  • apex_manifest.pb : تخزينها فقط
  • AndroidManifest.xml : تخزينها فقط
  • apex_pubkey : تخزينها فقط

و apex_manifest.pb ، AndroidManifest.xml و apex_pubkey الملفات هي نسخ من الملفات يناظرها في original_apex .

بناء مضغوط APEX

مضغوط APEX يمكن أن يبنى باستخدام apex_compression_tool.py أداة تقع في system/apex/tools .

تتوفر العديد من المعلمات المتعلقة بضغط APEX في نظام الإنشاء.

في Android.bp ما إذا كان ملف APEX هو انضغاط تسيطر عليها compressible الملكية:

apex {
    name: "apex.test",
    manifest: "apex_manifest.json",
    file_contexts: "file_contexts",
    compressible: true,
}

A PRODUCT_COMPRESSED_APEX ضوابط العلم المنتج سواء صورة نظام بنيت من مصدر يجب أن يحتوي على ضغط الملفات APEX.

للتجريب المحلي يمكنك فرض بناء على الرءوس ضغط عن طريق وضع OVERRIDE_PRODUCT_COMPRESSED_APEX= إلى true .

الملفات المضغوطة APEX الناتجة عن بناء نظام لديك .capex التمديد. يسهل الامتداد التمييز بين الإصدارات المضغوطة وغير المضغوطة لملف APEX.

خوارزميات الضغط المدعومة

يدعم Android 12 فقط ضغط الانكماش المضغوط.

تفعيل ملف APEX مضغوط أثناء الإقلاع

قبل أن تتمكن من تنشيط APEX مضغوط، و original_apex ملف داخل انها فك ضغط في /data/apex/decompressed الدليل. من الصعب مرتبطة الملف APEX ضغط مما أدى إلى /data/apex/active الدليل.

ضع في اعتبارك المثال التالي كتوضيح للعملية الموضحة أعلاه.

النظر /system/apex/com.android.foo.capex باعتباره APEX مضغوط يتم تفعيلها، مع كود الإصدار 37.

  1. و original_apex ملف داخل /system/apex/com.android.foo.capex ومخفف في /data/apex/decompressed/com.android.foo@37.apex .
  2. restorecon /data/apex/decompressed/com.android.foo@37.apex يتم تنفيذ للتحقق من أن لديها التسمية سيلينو الصحيحة.
  3. يتم تنفيذ التحقق الشيكات على /data/apex/decompressed/com.android.foo@37.apex لضمان صلاحيتها: apexd الشيكات المفتاح العمومي المجمعة في /data/apex/decompressed/com.android.foo@37.apex ل تحقق من أنه يساوي واحد واحدة في /system/apex/com.android.foo.capex .
  4. و /data/apex/decompressed/com.android.foo@37.apex الملف هو الثابت مرتبطة /data/apex/active/com.android.foo@37.apex الدليل.
  5. يتم تنفيذ المنطق تفعيل العادي للملفات APEX غير مضغوط على /data/apex/active/com.android.foo@37.apex .

التفاعل مع OTA

ملفات APEX المضغوطة لها آثار على تسليم وتطبيق OTA. نظرًا لأن تحديث OTA قد يحتوي على ملف APEX مضغوط بمستوى إصدار أعلى مما هو نشط على الجهاز ، يجب حجز قدر معين من المساحة الحرة قبل إعادة تشغيل الجهاز لتطبيق تحديث OTA.

لدعم النظام أوتا، apexd يعرض هذين اجهات برمجة التطبيقات الموثق:

  • calculateSizeForCompressedApex - يحسب حجم المطلوبة لملفات APEX التخلص من التوتر في حزمة OTA. يمكن استخدام هذا للتحقق من أن الجهاز به مساحة كافية قبل تنزيل OTA.
  • reserveSpaceForCompressedApex - احتياطيات المساحة على القرص لاستخدامها مستقبلا من قبل apexd عن فك الملفات المضغوطة APEX داخل الحزمة OTA.

في حالة تحديثا A / B OTA، apexd محاولات الضغط في الخلفية كجزء من postinstall OTA روتين. إذا فشل الضغط، apexd ينفذ تخفيف الضغط أثناء التمهيد الذي ينطبق التحديث OTA.

البدائل التي تم أخذها في الاعتبار عند تطوير APEX

فيما يلي بعض الخيارات التي أخذتها AOSP في الاعتبار عند تصميم تنسيق ملف APEX ، ولماذا تم تضمينها أو استبعادها.

أنظمة إدارة الحزم العادية

توزيعات لينكس لديها أنظمة إدارة الحزم مثل dpkg و rpm ، والتي هي قوية، وتنضج، وقوية. ومع ذلك ، لم يتم اعتمادها لـ APEX لأنها لا تستطيع حماية الحزم بعد التثبيت. يتم التحقق فقط عندما يتم تثبيت الحزم. يمكن للمهاجمين كسر تكامل الحزم المثبتة دون أن يلاحظها أحد. هذا هو الانحدار لنظام Android حيث تم تخزين جميع مكونات النظام في أنظمة ملفات للقراءة فقط والتي يتم حماية سلامتها بواسطة dm-verity لكل I / O. يجب إما حظر أي تلاعب في مكونات النظام ، أو يمكن اكتشافه بحيث يمكن للجهاز رفض التمهيد إذا تم اختراقه.

dm-crypt من أجل النزاهة

الملفات في وعاء APEX هي من المدمج في أقسام (على سبيل المثال، و /system التقسيم) التي تحميها DM-حقيقة، حيث يحظر على أي تعديل على الملفات حتى بعد هي التي شنت الأقسام. لتوفير نفس مستوى الأمان للملفات ، يتم تخزين جميع الملفات الموجودة في APEX في صورة نظام ملفات مقترنة بشجرة تجزئة وموصف vbmeta. بدون دسم، حقيقة، وهو APEX في /data التقسيم هو عرضة للتعديلات غير مقصودة التي يتم إجراؤها بعد تم التحقق منها وتثبيتها.

في الواقع، فإن /data محمي التقسيم أيضا طبقات التشفير مثل DM-سرداب. على الرغم من أن هذا يوفر مستوى معينًا من الحماية ضد العبث ، إلا أن الغرض الأساسي منه هو الخصوصية وليس النزاهة. عندما كان المهاجم المكاسب الوصول إلى /data التقسيم، يمكن أن يكون هناك أي حماية إضافية، وهذا مرة أخرى هو الانحدار مقابل كل مكون نظام يجري في /system التقسيم. توفر شجرة التجزئة داخل ملف APEX جنبًا إلى جنب مع dm-verity نفس مستوى حماية المحتوى.

إعادة توجيه المسارات من / system إلى / apex

نظام ملفات المكون حزم في APEX يمكن الوصول إليها عبر مسارات جديدة مثل /apex/<name>/lib/libfoo.so . عندما كانت الملفات جزء من /system التقسيم، كانوا يمكن الوصول إليها عبر مسارات مثل /system/lib/libfoo.so . يجب أن يستخدم عميل ملف APEX (ملفات APEX الأخرى أو النظام الأساسي) المسارات الجديدة. قد تحتاج إلى تحديث التعليمات البرمجية الموجودة كنتيجة لتغيير المسار.

على الرغم من أن طريقة واحدة لتجنب تغيير مسار هو تراكب محتويات الملف في ملف APEX على /system التقسيم، قرر فريق الروبوت عدم ملفات تراكب على /system التقسيم لأن هذا يمكن أن يؤثر على الأداء حيث بلغ عدد الملفات التي يتم تراكب إعلان ( ربما مكدسة واحدة تلو الأخرى).

وثمة خيار آخر لخطف ظائف الوصول إلى الملفات مثل open ، stat ، و readlink ، بحيث مسارات بدءا من /system تم إعادة توجيهها إلى مسارات يناظرها تحت /apex . تجاهل فريق Android هذا الخيار لأنه من غير الممكن تغيير جميع الوظائف التي تقبل المسارات. على سبيل المثال ، تربط بعض التطبيقات Bionic بشكل ثابت ، والتي تقوم بتنفيذ الوظائف. في مثل هذه الحالات ، لا تتم إعادة توجيه هذه التطبيقات.