รูปแบบไฟล์ APEX

รูปแบบคอนเทนเนอร์ Android Pony EXpress (APEX) ถูกนำมาใช้ใน Android 10 และใช้ในโฟลว์การติดตั้งสำหรับโมดูลระบบระดับล่าง รูปแบบนี้อำนวยความสะดวกในการอัปเดตส่วนประกอบของระบบที่ไม่เข้ากับรุ่นแอปพลิเคชัน Android มาตรฐาน บางชิ้นส่วนตัวอย่างเช่นบริการพื้นเมืองและห้องสมุดชั้น abstraction ฮาร์ดแวร์ ( HAL ที่ ) รันไทม์ ( ART ) และห้องสมุดชั้น

คำว่า "APEX" ยังหมายถึงไฟล์ APEX

พื้นหลัง

แม้ว่า Android จะรองรับการอัปเดตโมดูลที่พอดีกับรุ่นแอปมาตรฐาน (เช่น บริการ กิจกรรม) ผ่านแอปตัวติดตั้งแพ็กเกจ (เช่น แอป Google Play Store) การใช้รุ่นที่คล้ายกันสำหรับส่วนประกอบ OS ระดับล่างจะมีข้อเสียดังต่อไปนี้:

  • ใช้โมดูลที่ใช้ APK ในช่วงเริ่มต้นของลำดับการบูตไม่ได้ ตัวจัดการแพ็คเกจคือที่เก็บข้อมูลส่วนกลางของข้อมูลเกี่ยวกับแอพ และสามารถเริ่มต้นได้จากตัวจัดการกิจกรรมเท่านั้น ซึ่งจะพร้อมใช้งานในขั้นตอนต่อไปของขั้นตอนการบู๊ต
  • รูปแบบ APK (โดยเฉพาะไฟล์ Manifest) ได้รับการออกแบบมาสำหรับแอป Android และโมดูลระบบอาจไม่เหมาะเสมอไป

ออกแบบ

ส่วนนี้อธิบายการออกแบบระดับสูงของรูปแบบไฟล์ APEX และตัวจัดการ APEX ซึ่งเป็นบริการที่จัดการไฟล์ APEX

สำหรับข้อมูลเพิ่มเติมเกี่ยวกับเหตุผลที่การออกแบบนี้สำหรับ APEX ได้รับเลือกให้ดู ทางเลือกในการพิจารณาเมื่อการพัฒนา APEX

รูปแบบ APEX

นี่คือรูปแบบของไฟล์ APEX

รูปแบบไฟล์ APEX

รูปแบบไฟล์รูปที่ 1 APEX

ที่ระดับบนสุด ไฟล์ APEX เป็นไฟล์ zip ซึ่งไฟล์จะถูกจัดเก็บแบบไม่บีบอัดและอยู่ที่ขอบเขต 4 KB

สี่ไฟล์ในไฟล์ APEX คือ:

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

apex_manifest.json ไฟล์มีชื่อแพคเกจและรุ่นซึ่งระบุไฟล์ APEX

AndroidManifest.xml ไฟล์ช่วยให้ไฟล์ APEX กับการใช้เครื่องมือที่เกี่ยวข้องกับเอพีเคและโครงสร้างพื้นฐานเช่น ADB, PackageManager และแอปติดตั้งแพคเกจ (เช่น Play Store) ยกตัวอย่างเช่นแฟ้ม 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. ฐานติดตั้งอุปกรณ์ป้องกัน mapper อุปกรณ์บนเส้นทางที่ไม่ซ้ำกัน (เช่น /apex/ name @ ver )

เมื่อไฟล์ APEX ทั้งหมดที่ระบุไว้ในฐานข้อมูลภายในถูกเมาต์ ตัวจัดการ APEX จะให้บริการตัวประสานสำหรับส่วนประกอบระบบอื่นๆ เพื่อสอบถามข้อมูลเกี่ยวกับไฟล์ APEX ที่ติดตั้ง ตัวอย่างเช่น ส่วนประกอบอื่นๆ ของระบบสามารถสืบค้นรายการไฟล์ APEX ที่ติดตั้งในอุปกรณ์หรือค้นหาเส้นทางที่แน่นอนซึ่งติดตั้ง APEX เฉพาะ เพื่อให้สามารถเข้าถึงไฟล์ได้

ไฟล์ APEX เป็นไฟล์ APK

ไฟล์ APEX มีไฟล์ APK ที่ถูกต้องเพราะพวกเขากำลังลงนามไปรษณีย์ที่เก็บ (โดยใช้รูปแบบลายเซ็นเอพีเค) การที่มี AndroidManifest.xml ไฟล์ ซึ่งช่วยให้ไฟล์ APEX ใช้โครงสร้างพื้นฐานสำหรับไฟล์ APK เช่น แอพตัวติดตั้งแพ็คเกจ ยูทิลิตี้การลงนาม และตัวจัดการแพ็คเกจ

AndroidManifest.xml ไฟล์ภายในไฟล์ APEX มีน้อยประกอบด้วยแพคเกจ name , versionCode และตัวเลือก targetSdkVersion , minSdkVersion และ maxSdkVersion สำหรับการกำหนดเป้าหมายเม็ดเล็ก ข้อมูลนี้อนุญาตให้ส่งไฟล์ APEX ผ่านช่องทางที่มีอยู่ เช่น แอพตัวติดตั้งแพ็คเกจและ ADB

รองรับประเภทไฟล์

รูปแบบ APEX รองรับประเภทไฟล์เหล่านี้:

  • Native libs ที่ใช้ร่วมกัน
  • ไฟล์ปฏิบัติการดั้งเดิม
  • ไฟล์ JAR
  • ไฟล์ข้อมูล
  • ไฟล์คอนฟิก

ไม่ได้หมายความว่า APEX สามารถอัปเดตไฟล์ประเภทนี้ได้ทั้งหมด การจะอัพเดตประเภทไฟล์ได้หรือไม่นั้นขึ้นอยู่กับแพลตฟอร์มและความเสถียรของคำจำกัดความของอินเทอร์เฟซสำหรับประเภทไฟล์

การลงนาม

ไฟล์ APEX มีการลงนามในสองวิธี ครั้งแรกที่ apex_payload.img (เฉพาะบ่ง vbmeta ต่อท้าย apex_payload.img ) แฟ้มจะเซ็นสัญญากับคีย์ จากนั้นทั้ง APEX มีการลงนามโดยใช้ เอพีเคลายเซ็นโครงการ v3 กระบวนการนี้ใช้คีย์ที่แตกต่างกันสองปุ่ม

ที่ด้านอุปกรณ์ มีการติดตั้งคีย์สาธารณะที่สอดคล้องกับคีย์ส่วนตัวที่ใช้ในการลงนาม vbmeta descriptor ตัวจัดการ APEX ใช้กุญแจสาธารณะเพื่อตรวจสอบ APEX ที่ได้รับการร้องขอให้ติดตั้ง APEX แต่ละรายการต้องลงนามด้วยคีย์ที่แตกต่างกัน และบังคับใช้ทั้งในเวลาบิลด์และรันไทม์

APEX ในพาร์ติชั่นในตัว

ไฟล์ APEX สามารถตั้งอยู่ในในตัวพาร์ทิชันเช่น /system พาร์ติชั่นอยู่เหนือ dm-verity อยู่แล้ว ดังนั้นไฟล์ APEX จะถูกเมาต์โดยตรงบนอุปกรณ์ลูปแบ็ค

หากมี APEX ในพาร์ติชั่นในตัว APEX สามารถอัพเดตได้โดยการจัดเตรียมแพ็คเกจ APEX ที่มีชื่อแพ็คเกจเดียวกันและมากกว่าหรือเท่ากับโค้ดเวอร์ชัน เอเพ็กซ์ใหม่จะถูกเก็บไว้ใน /data และคล้ายกับ APK ที่ที่ติดตั้งใหม่รุ่นเงารุ่นอยู่แล้วในตัวในพาร์ทิชัน แต่ต่างจาก APK APEX เวอร์ชันที่ติดตั้งใหม่จะเปิดใช้งานหลังจากรีบูตเท่านั้น

ข้อกำหนดเคอร์เนล

เพื่อรองรับโมดูล APEX mainline บนอุปกรณ์ Android จำเป็นต้องมีคุณลักษณะเคอร์เนล Linux ต่อไปนี้: ไดรเวอร์ลูปแบ็คและ dm-verity ไดรเวอร์ลูปแบ็คจะเมาต์อิมเมจระบบไฟล์ในโมดูล APEX และ dm-verity จะตรวจสอบโมดูล APEX

ประสิทธิภาพของไดรเวอร์ลูปแบ็คและ dm-verity มีความสำคัญในการบรรลุประสิทธิภาพของระบบที่ดีเมื่อใช้โมดูล APEX

เวอร์ชันเคอร์เนลที่รองรับ

โมดูลเมนไลน์ APEX ได้รับการสนับสนุนบนอุปกรณ์ที่ใช้เคอร์เนลเวอร์ชัน 4.4 หรือสูงกว่า อุปกรณ์ใหม่ที่เปิดตัวด้วย Android 10 หรือสูงกว่าต้องใช้เคอร์เนลเวอร์ชัน 4.9 หรือสูงกว่าเพื่อรองรับโมดูล APEX

แพตช์เคอร์เนลที่จำเป็น

แพตช์เคอร์เนลที่จำเป็นสำหรับการสนับสนุนโมดูล APEX จะรวมอยู่ในทรีทั่วไปของ Android หากต้องการรับแพตช์เพื่อรองรับ APEX ให้ใช้เวอร์ชันล่าสุดของแผนผังทั่วไปของ Android

เคอร์เนลเวอร์ชัน4.4

เวอร์ชันนี้รองรับเฉพาะอุปกรณ์ที่อัปเกรดจาก Android 9 เป็น Android 10 และต้องการรองรับโมดูล APEX ที่จะได้รับแพทช์ที่จำเป็นลงผสานจาก android-4.4 สาขาขอแนะนำ ต่อไปนี้คือรายการแพตช์แต่ละรายการที่จำเป็นสำหรับเคอร์เนลเวอร์ชัน 4.4

  • ต้นน้ำ: ห่วง: เพิ่ม IOCTL สำหรับการเปลี่ยนขนาดของบล็อกตรรกะ ( 4.4 )
  • ย้ายกลับ: บล็อก / ห่วง: ตั้ง hw_sectors ( 4.4 )
  • ต้นน้ำ: ห่วง: เพิ่ม LOOP_SET_BLOCK_SIZE ใน IOCTL compat ( 4.4 )
  • ANDROID: mnt: แก้ไข next_descendent ( 4.4 )
  • ANDROID: mnt: remount ควรเผยแพร่สู่ทาสทาส ( 4.4 )
  • ANDROID: mnt: การเผยแพร่อย่างถูกต้องต่อเชื่อม ( 4.4 )
  • เปลี่ยนกลับ "Android: dm จริง: เพิ่มขนาด prefetch ขั้นต่ำ" ( 4.4 )
  • ต้นน้ำ: ห่วง: แคชลดลงถ้าชดเชยหรือ block_size มีการเปลี่ยนแปลง ( 4.4 )

เวอร์ชันเคอร์เนล 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

ข้อกำหนดพารามิเตอร์บรรทัดคำสั่งเคอร์เนล

เพื่อรองรับ APEX ตรวจสอบให้แน่ใจว่าพารามิเตอร์บรรทัดคำสั่งเคอร์เนลตรงตามข้อกำหนดต่อไปนี้:

  • 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
ไลบรารี Java /javalib
สร้างไว้ล่วงหน้า /etc

การพึ่งพาสกรรมกริยา

ไฟล์ APEX จะรวมการพึ่งพาสกรรมกริยาของ libs ที่แชร์หรือไฟล์เรียกทำงานแบบเนทีฟโดยอัตโนมัติ ตัวอย่างเช่นถ้า libFoo ขึ้นอยู่กับ libBar ทั้งสองจะรวม libs เมื่อเพียง libFoo มีชื่ออยู่ใน native_shared_libs คุณสมบัติ

การจัดการ ABI หลายตัว

ติดตั้ง native_shared_libs อสังหาริมทรัพย์สำหรับทั้งประถมศึกษาและมัธยมศึกษาอินเตอร์เฟซการประยุกต์ใช้ไบนารี (ABIs) ของอุปกรณ์ หาก APEX กำหนดเป้าหมายอุปกรณ์ด้วย ABI เดียว (นั่นคือ 32 บิตเท่านั้นหรือ 64 บิตเท่านั้น) เฉพาะไลบรารีที่มี ABI ที่เกี่ยวข้องเท่านั้นที่จะได้รับการติดตั้ง

ติดตั้ง binaries คุณสมบัติเฉพาะสำหรับหลัก ABI ของอุปกรณ์ตามที่อธิบายไว้ด้านล่าง:

  • หากอุปกรณ์เป็นแบบ 32 บิตเท่านั้น จะมีการติดตั้งไบนารีแบบ 32 บิตเท่านั้น
  • หากอุปกรณ์เป็น 64 บิตเท่านั้น จะมีการติดตั้งไบนารีรุ่น 64 บิตเท่านั้น

หากต้องการเพิ่มการควบคุมที่ละเอียดมากกว่า ABIs ของห้องสมุดพื้นเมืองและไบนารีใช้ multilib.[first|lib32|lib64|prefer32|both].[native_shared_libs|binaries] คุณสมบัติ

  • first : ตรงกับหลัก ABI ของอุปกรณ์ นี่เป็นค่าเริ่มต้นสำหรับไบนารี
  • lib32 : แมตช์ 32 บิต ABI ของอุปกรณ์ถ้าได้รับการสนับสนุน
  • lib64 : แมตช์ 64 บิต ABI ของอุปกรณ์ที่มันได้รับการสนับสนุน
  • prefer32 : แมตช์ 32 บิต ABI ของอุปกรณ์ถ้าได้รับการสนับสนุน หากไม่รองรับ ABI แบบ 32 บิต ให้จับคู่กับ ABI แบบ 64 บิต
  • both แมตช์ทั้ง ABIs นี่คือการเริ่มต้นสำหรับ 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 ) กลายเป็น ID ของคีย์ รหัสของคีย์ที่ใช้ลงนามใน APEX เขียนไว้ใน APEX ที่รันไทม์ apexd สามารถตรวจสอบ APEX ใช้กุญแจสาธารณะที่มีรหัสเดียวกันในเครื่อง

เซ็นไปรษณีย์

ลงนาม APEX ในลักษณะเดียวกับที่คุณลงนาม APK ลงนาม APEX สองครั้ง; ครั้งเดียวสำหรับระบบไฟล์ขนาดเล็ก ( apex_payload.img ไฟล์) และอีกครั้งสำหรับไฟล์ทั้งหมด

จะลงนามใน APEX ที่ระดับไฟล์ให้ตั้ง certificate คุณสมบัติในหนึ่งของทั้งสามวิธี:

  • ไม่ได้ตั้งค่า: ถ้าไม่มีค่าถูกตั้งค่า APEX มีการลงนามกับใบรับรองอยู่ที่ PRODUCT_DEFAULT_DEV_CERTIFICATE หากไม่มีการตั้งธงเริ่มต้นเส้นทางที่จะ build/target/product/security/testkey
  • <name> : เอเพ็กซ์มีการลงนามกับ <name> ใบรับรองในไดเรกทอรีเดียวกันกับ PRODUCT_DEFAULT_DEV_CERTIFICATE
  • :<name> : เอเพ็กซ์มีการลงนามกับใบรับรองที่ถูกกำหนดโดยโมดูล Soong ชื่อ <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_name>@<version> ไดเรกทอรี APEX เดียวกันได้หลายเวอร์ชันสามารถติดตั้งได้พร้อมกัน ท่ามกลางภูเขาเส้นทางหนึ่งที่สอดคล้องกับรุ่นล่าสุดคือการผูกติดที่ /apex/<apex_name>

ลูกค้าสามารถใช้พาธที่ผูกมัดเพื่ออ่านหรือรันไฟล์จาก APEX

APEX มักใช้ดังนี้:

  1. OEM หรือ ODM preloads 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 ไม่รองรับทริกเกอร์การดำเนินการใน APEX

หากบริการที่ทำเครื่องหมายว่าสามารถอัปเดตได้เริ่มต้นก่อนเปิดใช้งาน APEX การเริ่มต้นจะล่าช้าจนกว่าการเปิดใช้งาน APEX จะเสร็จสิ้น

การกำหนดค่าระบบเพื่อรองรับการอัพเดต 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

Flattened 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 ที่แบนราบได้โดยการดาวน์โหลด APEX เวอร์ชันที่อัปเดตจากเครือข่าย เนื่องจาก APEX ที่ดาวน์โหลดมาจะไม่สามารถทำให้แบนได้ APEX แบบแบนสามารถอัปเดตผ่าน OTA ปกติเท่านั้น

APEX แบบแบนคือการกำหนดค่าเริ่มต้น ซึ่งหมายความว่า APEX ทั้งหมดจะถูกทำให้แบนโดยค่าเริ่มต้น เว้นแต่คุณจะกำหนดค่าอุปกรณ์ของคุณอย่างชัดเจนเพื่อสร้าง APEX ที่ไม่แบนเพื่อรองรับการอัปเดต APEX (ตามที่อธิบายไว้ข้างต้น)

ไม่รองรับการผสม APEX แบบแบนและไม่แบนในอุปกรณ์ APEX ในอุปกรณ์ต้องไม่แบนทั้งหมดหรือแบนทั้งหมด สิ่งนี้มีความสำคัญอย่างยิ่งเมื่อจัดส่ง APEX ที่สร้างไว้ล่วงหน้า APEX ที่ลงนามล่วงหน้าสำหรับโครงการต่างๆ เช่น Mainline APEX ที่ไม่ได้กำหนดไว้ล่วงหน้า (ซึ่งก็คือ สร้างขึ้นจากแหล่งที่มา) ไม่ควรทำให้แบนราบและลงนามด้วยคีย์ที่เหมาะสม อุปกรณ์ที่ควรสืบทอดจาก updatable_apex.mk ที่อธิบายไว้ใน การอัปเดตการบริการที่มี APEX

APEX ที่บีบอัด

Android 12 และใหม่กว่ามีการบีบอัด APEX เพื่อลดผลกระทบของการจัดเก็บข้อมูลของแพ็คเกจ APEX ที่อัปเดตได้ หลังจากติดตั้งการอัปเดต APEX แล้ว แม้ว่าเวอร์ชันที่ติดตั้งไว้ล่วงหน้าจะไม่ได้ใช้อีกต่อไป แต่ก็ยังใช้พื้นที่ในปริมาณเท่าเดิม พื้นที่ที่ถูกครอบครองนั้นยังคงใช้งานไม่ได้

การบีบอัด APEX ช่วยลดผลกระทบต่อการจัดเก็บข้อมูลโดยใช้ชุดการบีบอัดสูงของไฟล์ที่ APEX บนพาร์ติชันอ่านอย่างเดียว (เช่น /system พาร์ทิชัน) Android 12 และใหม่กว่าใช้อัลกอริธึมการบีบอัด DEFLATE zip

การบีบอัดไม่ได้เพิ่มประสิทธิภาพให้กับสิ่งต่อไปนี้:

  • Bootstrap APEX ที่จำเป็นต้องต่อเชื่อมตั้งแต่เนิ่นๆ ในลำดับการบู๊ต

  • APEX ที่ไม่สามารถอัปเดตได้ การบีบอัดเป็นประโยชน์เฉพาะในกรณีที่การปรับปรุงรุ่นของ APEX ติดตั้งอยู่บน /data พาร์ทิชัน รายการเต็มรูปแบบของ apexes สามารถปรับปรุงที่มีอยู่ใน ระบบ Modular ส่วนประกอบ หน้า

  • libs APEX ที่แชร์แบบไดนามิก ตั้งแต่ apexd เสมอเปิดใช้งานทั้งสองรุ่นดังกล่าว apexes (ติดตั้งและปรับ), บีบอัดไม่ได้เพิ่มคุณค่า

รูปแบบไฟล์ APEX ที่บีบอัด

นี่คือรูปแบบของไฟล์ APEX ที่บีบอัด

Diagram shows the format of a compressed APEX file

รูปแบบไฟล์รูปที่ 2 ที่บีบอัด APEX

ที่ระดับบนสุด ไฟล์ APEX ที่บีบอัดเป็นไฟล์ zip ที่มีไฟล์ 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,
}

PRODUCT_COMPRESSED_APEX ควบคุมธงผลิตภัณฑ์ไม่ว่าจะเป็นระบบภาพที่สร้างขึ้นจากแหล่งที่จะต้องมีการบีบอัดไฟล์ APEX

สำหรับการทดลองท้องถิ่นที่คุณสามารถบังคับให้สร้างเพื่อ apexes บีบอัดโดยการตั้งค่า OVERRIDE_PRODUCT_COMPRESSED_APEX= เพื่อ true

อัด APEX ไฟล์ที่สร้างขึ้นโดยการสร้างระบบมี .capex ขยาย ส่วนขยายทำให้แยกความแตกต่างระหว่างไฟล์ APEX เวอร์ชันบีบอัดและไม่บีบอัดได้ง่ายขึ้น

อัลกอริธึมการบีบอัดที่รองรับ

Android 12 รองรับเฉพาะการบีบอัด deflate-zip

การเปิดใช้งานไฟล์ APEX ที่บีบอัดระหว่างการบู๊ต

ก่อนที่จะมีการบีบอัด APEX สามารถเปิดใช้งาน original_apex แฟ้มที่อยู่ภายในก็แตกเข้าไปใน /data/apex/decompressed ไดเรกทอรี แฟ้ม APEX ส่งผลให้แตกเป็นเรื่องยากที่เชื่อมโยงไปยัง /data/apex/active ไดเรกทอรี

พิจารณาตัวอย่างต่อไปนี้เป็นตัวอย่างของกระบวนการที่อธิบายไว้ข้างต้น

พิจารณา /system/apex/com.android.foo.capex เป็นบีบอัด APEX ถูกเปิดใช้งานกับ versionCode 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 จะดำเนินการเพื่อตรวจสอบว่ามีฉลาก SELinux ที่ถูกต้อง
  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

เพื่อสนับสนุนระบบ OTA, apexd exposes ทั้งสอง APIs เครื่องผูก:

  • 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 จะถูกเก็บไว้ในอิมเมจระบบไฟล์ที่จับคู่กับ hash tree และ vbmeta descriptor โดยไม่ต้อง DM-สิ่งที่เป็นจริงเป็น 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 พาร์ทิชันทีมงาน Android ตัดสินใจที่จะไม่ไฟล์ภาพซ้อนทับบน /system พาร์ทิชันเพราะนี้อาจส่งผลกระทบต่อผลการดำเนินงานเป็นจำนวนไฟล์ที่มีการซ้อนทับ ( อาจจะซ้อนกันก็ได้) เพิ่มขึ้น

อีกตัวเลือกหนึ่งคือการจี้ฟังก์ชั่นไฟล์การเข้าถึงเช่น open , stat และ readlink เพื่อให้เส้นทางที่เริ่มต้นด้วย /system ถูกเปลี่ยนเส้นทางไปยังเส้นทางที่สอดคล้องกันของพวกเขาภายใต้ /apex ทีมงาน Android ละทิ้งตัวเลือกนี้เนื่องจากไม่สามารถเปลี่ยนฟังก์ชันทั้งหมดที่ยอมรับเส้นทางได้ ตัวอย่างเช่น แอพบางตัวเชื่อมโยง Bionic แบบคงที่ ซึ่งใช้งานฟังก์ชั่นต่างๆ ในกรณีดังกล่าว แอปเหล่านั้นจะไม่ถูกเปลี่ยนเส้นทาง