เปิดตัวรูปแบบคอนเทนเนอร์ Android Pony EXpress (APEX) ใน Android 10 คน และใช้ในขั้นตอนการติดตั้งสำหรับระบบระดับล่าง โมดูล รูปแบบนี้ช่วยให้อัปเดตคอมโพเนนต์ของระบบที่ไม่พอดีได้ง่ายขึ้น เป็นโมเดลแอปพลิเคชัน Android มาตรฐาน คอมโพเนนต์ตัวอย่างบางรายการเป็นแบบเนทีฟ บริการและไลบรารี ชั้นการจัดการฮาร์ดแวร์ (HAL), รันไทม์ (ART) และห้องสมุดของชั้นเรียน
คำว่า "APEX" สามารถอ้างอิงไฟล์ APEX ได้ด้วย
ฉากหลัง
แม้ว่า Android จะรองรับการอัปเดตโมดูลที่พอดีกับแอปมาตรฐาน โมเดล (เช่น บริการ กิจกรรม) ผ่านแอปโปรแกรมติดตั้งแพ็กเกจ (เช่น แอป Google Play Store) ซึ่งใช้โมเดลที่คล้ายกันสำหรับคอมโพเนนต์ระบบปฏิบัติการระดับต่ำกว่า มีข้อเสียดังต่อไปนี้
- โมดูลที่ใช้ APK จะใช้ในลำดับการเปิดเครื่องไม่ได้ในตอนต้น แพ็กเกจ เป็นที่เก็บส่วนกลาง ที่รวบรวมข้อมูลเกี่ยวกับแอปต่างๆ และ เริ่มจากเครื่องมือจัดการกิจกรรม ซึ่งจะพร้อมใช้งานในขั้นตอนต่อไป ขั้นตอนการเปิดเครื่อง
- รูปแบบ APK (โดยเฉพาะไฟล์ Manifest) ได้รับการออกแบบมาสำหรับแอป Android และ โมดูลระบบอาจไม่ถูกต้องเสมอไป
การออกแบบ
ส่วนนี้จะอธิบายการออกแบบระดับสูงของรูปแบบไฟล์ APEX และ ตัวจัดการ APEX ซึ่งเป็นบริการจัดการไฟล์ APEX
สำหรับข้อมูลเพิ่มเติมเกี่ยวกับเหตุผลที่เลือกการออกแบบนี้สำหรับ APEX โปรดดู ทางเลือกที่นำมาพิจารณาเมื่อพัฒนา APEX
รูปแบบ APEX
นี่คือรูปแบบของไฟล์ APEX
รูปที่ 1 รูปแบบไฟล์ APEX
ที่ระดับบนสุด ไฟล์ APEX คือไฟล์ ZIP ที่ใช้จัดเก็บไฟล์ ไม่ได้บีบอัดและมีขนาดอยู่ที่ 4 KB
ไฟล์ APEX 4 ไฟล์มีดังนี้
apex_manifest.json
AndroidManifest.xml
apex_payload.img
apex_pubkey
ไฟล์ apex_manifest.json
มีชื่อแพ็กเกจและเวอร์ชันของ
ระบุไฟล์ APEX นี่คือ
ApexManifest
บัฟเฟอร์โปรโตคอลในรูปแบบ JSON
ไฟล์ AndroidManifest.xml
ช่วยให้ไฟล์ APEX สามารถใช้เครื่องมือที่เกี่ยวข้องกับ APK และ
โครงสร้างพื้นฐาน เช่น ADB, PackageManager และแอปโปรแกรมติดตั้งแพ็กเกจ (เช่น
Play Store) ตัวอย่างเช่น ไฟล์ APEX สามารถใช้เครื่องมือที่มีอยู่ เช่น aapt
เพื่อตรวจสอบข้อมูลเมตาพื้นฐานจากไฟล์ ไฟล์มีชื่อแพ็กเกจและ
ข้อมูลเวอร์ชัน โดยทั่วไปแล้ว ข้อมูลนี้มีอยู่ใน
apex_manifest.json
แนะนำให้ใช้ apex_manifest.json
มากกว่า AndroidManifest.xml
สำหรับโค้ดใหม่และ
ระบบที่ทำงานกับ APEX AndroidManifest.xml
อาจมี
ข้อมูลการกำหนดเป้าหมายที่เครื่องมือเผยแพร่แอปที่มีอยู่สามารถใช้ได้
apex_payload.img
คืออิมเมจระบบไฟล์ ext4 ที่ได้รับการสนับสนุนโดย dm-verity รูปภาพ
จะต่อเชื่อมขณะรันไทม์ผ่านอุปกรณ์ Loopback โดยเฉพาะอย่างยิ่ง โครงสร้างแฮชและ
บล็อกข้อมูลเมตาสร้างขึ้นโดยใช้ไลบรารี libavb
เพย์โหลดระบบไฟล์
ไม่ได้แยกวิเคราะห์ (เนื่องจากรูปภาพควรติดตั้งได้ในตำแหน่ง) ไฟล์ทั่วไปคือ
ซึ่งรวมอยู่ในไฟล์ apex_payload.img
apex_pubkey
เป็นคีย์สาธารณะที่ใช้ในการลงนามอิมเมจระบบไฟล์ ระหว่างรันไทม์
คีย์นี้ช่วยให้ APEX ที่ดาวน์โหลดมามีการลงชื่อด้วยเอนทิตีเดียวกัน
ที่ลงชื่อ APEX เดียวกันในพาร์ติชันในตัว
หลักเกณฑ์การตั้งชื่อ APEX
เพื่อช่วยป้องกันความขัดแย้งในการตั้งชื่อระหว่าง APEX ใหม่ในขณะที่แพลตฟอร์มก้าวหน้า ใช้หลักเกณฑ์การตั้งชื่อดังต่อไปนี้
com.android.*
- สงวนไว้สำหรับ AOSP APEXes ไม่เจาะจงสำหรับบริษัทหรืออุปกรณ์ใดๆ
com.<companyname>.*
- สงวนไว้สำหรับบริษัท อุปกรณ์หลายเครื่องที่อาจใช้งานอยู่ บริษัท
com.<companyname>.<devicename>.*
- สงวนไว้สำหรับ APEX เฉพาะกับอุปกรณ์หนึ่งๆ (หรืออุปกรณ์ชุดย่อย)
ผู้จัดการ APEX
เครื่องมือจัดการ APEX (หรือ apexd
) เป็นกระบวนการแบบเนทีฟแบบสแตนด์อโลนที่รับผิดชอบ
ยืนยัน ติดตั้ง และถอนการติดตั้งไฟล์ APEX กระบวนการนี้เริ่มใช้แล้ว และ
พร้อมใช้งานในช่วงต้นของลำดับการเปิดเครื่อง โดยปกติไฟล์ APEX จะได้รับการติดตั้งไว้ล่วงหน้า
อุปกรณ์ภายใต้ /system/apex
เครื่องมือจัดการ APEX จะใช้ค่าเริ่มต้น
หากไม่มีการอัปเดตพร้อมใช้งาน
ลำดับการอัปเดตของ APEX จะใช้ คลาส PackageManager และมีดังนี้
- ไฟล์ APEX จะดาวน์โหลดผ่านแอปโปรแกรมติดตั้งแพ็กเกจ, ADB หรือ แหล่งที่มา
- ตัวจัดการแพ็กเกจจะเริ่มขั้นตอนการติดตั้ง เมื่อตระหนักว่า ไฟล์นี้เป็น APEX ตัวจัดการแพ็กเกจจะโอนการควบคุมไปยัง APEX
- ผู้จัดการ APEX จะยืนยันไฟล์ APEX
- หากไฟล์ APEX ได้รับการยืนยันแล้ว ฐานข้อมูลภายในของตัวจัดการ APEX จะเป็น อัปเดตเพื่อให้แสดงว่าไฟล์ APEX เปิดใช้งานเมื่อเปิดเครื่องครั้งถัดไป
- ผู้ส่งคำขอติดตั้งจะได้รับการออกอากาศเมื่อแพ็กเกจเสร็จสมบูรณ์ การยืนยันของคุณ
- หากต้องการติดตั้งต่อ คุณต้องรีบูตระบบ
เมื่อเปิดเครื่องครั้งถัดไป ตัวจัดการ APEX จะเริ่มต้น อ่านฐานข้อมูลภายใน และ ค่าต่อไปนี้สำหรับไฟล์ APEX แต่ละไฟล์ที่ระบุ
- ยืนยันไฟล์ APEX
- สร้างอุปกรณ์ Loopback จากไฟล์ APEX
- สร้างอุปกรณ์บล็อกตัวแมปอุปกรณ์ที่ด้านบนของอุปกรณ์ Loopback
- ติดตั้งอุปกรณ์บล็อกตัวทำแผนที่อุปกรณ์เข้ากับเส้นทางที่ไม่ซ้ำกัน (เช่น
/apex/name@ver
)
เมื่อไฟล์ APEX ทั้งหมดที่ระบุไว้ในฐานข้อมูลภายในถูกต่อเชื่อมแล้ว APEX Manager ให้บริการ Binder สำหรับคอมโพเนนต์อื่นๆ ของระบบเพื่อค้นหา ข้อมูลเกี่ยวกับไฟล์ APEX ที่ติดตั้ง ตัวอย่างเช่น อีกระบบหนึ่ง สามารถค้นหารายการไฟล์ APEX ที่ติดตั้งในอุปกรณ์หรือค้นหา เส้นทางที่แน่นอนซึ่งมีการต่อเชื่อม APEX ที่เฉพาะเจาะจงเพื่อให้เข้าถึงไฟล์ได้
ไฟล์ APEX คือไฟล์ APK
ไฟล์ APEX เป็นไฟล์ APK ที่ถูกต้อง เนื่องจากเป็นไฟล์ ZIP ที่มีการรับรอง (โดยใช้
APK Signature Scheme) ที่มีไฟล์ AndroidManifest.xml
ซึ่งทำให้ APEX
เพื่อใช้โครงสร้างพื้นฐานสำหรับไฟล์ APK เช่น แอปโปรแกรมติดตั้งแพ็กเกจ
ยูทิลิตีการลงชื่อ และโปรแกรมจัดการแพ็กเกจ
ไฟล์ AndroidManifest.xml
ภายในไฟล์ APEX เป็นไฟล์เล็กที่สุด โดยประกอบด้วย
แพ็กเกจ name
, versionCode
และแพ็กเกจที่ไม่บังคับ targetSdkVersion
, minSdkVersion
และ maxSdkVersion
สำหรับการกำหนดเป้าหมายแบบละเอียด ข้อมูลนี้ช่วยให้ APEX
ส่งผ่านช่องทางที่มีอยู่ เช่น แอปโปรแกรมติดตั้งแพ็กเกจ และ
ADB
ประเภทไฟล์ที่รองรับ
รูปแบบ APEX รองรับไฟล์ประเภทต่อไปนี้
- Libs ที่แชร์แบบเนทีฟ
- ไฟล์ปฏิบัติการที่มาพร้อมเครื่อง
- ไฟล์ JAR
- ไฟล์ข้อมูล
- ไฟล์การกำหนดค่า
ซึ่งไม่ได้หมายความว่า APEX จะอัปเดตประเภทไฟล์เหล่านี้ได้ทั้งหมด เป็นไฟล์หรือไม่ ประเภทการอัปเดตจะขึ้นอยู่กับแพลตฟอร์ม และความเสถียรของคำจำกัดความของ อินเทอร์เฟซสำหรับประเภทไฟล์มีดังนี้
ตัวเลือกการรับรอง
ไฟล์ APEX จะมีการลงชื่อ 2 วิธี ก่อนอื่น apex_payload.img
(โดยเฉพาะ
ตัวบ่งชี้ vbmeta ที่ต่อท้าย apex_payload.img
) จะได้รับการลงนามด้วยคีย์
จากนั้น APEX ทั้งหมดจะลงชื่อโดยใช้
APK Signature Scheme v3 มีการใช้คีย์ที่แตกต่างกัน 2 คีย์
ในขั้นตอนนี้
ทางฝั่งอุปกรณ์ คีย์สาธารณะที่สอดคล้องกับคีย์ส่วนตัวที่ใช้ในการลงนาม ติดตั้งข้อบ่งชี้ vbmeta แล้ว เครื่องมือจัดการ APEX จะใช้คีย์สาธารณะเพื่อ ตรวจสอบ APEX ที่ถูกขอให้ติดตั้ง APEX แต่ละรายการต้องลงนาม คีย์ที่แตกต่างกันและมีการบังคับใช้ทั้งในเวลาบิลด์และรันไทม์
APEX ในพาร์ติชันในตัว
ไฟล์ APEX อาจอยู่ในพาร์ติชันในตัว เช่น /system
พาร์ติชันมีค่ามากกว่า dm-verity แล้ว ดังนั้นไฟล์ APEX จะถูกต่อเชื่อมโดยตรง
ผ่านทางอุปกรณ์ Loopback
ถ้ามี APEX อยู่ในพาร์ติชันในตัว คุณสามารถอัปเดต APEX ได้โดยดำเนินการดังนี้
แสดงแพ็กเกจ APEX ที่มีชื่อแพ็กเกจเดียวกันและมีมูลค่ามากกว่าหรือเท่ากับ
เป็นรหัสเวอร์ชัน APEX ใหม่ถูกจัดเก็บไว้ใน /data
และเช่นเดียวกับ APK
เวอร์ชันที่ติดตั้งใหม่จะแสดงเงาของเวอร์ชันที่มีอยู่แล้ว
พาร์ติชัน แต่ APEX แตกต่างจาก APK ตรงที่เวอร์ชัน APEX ที่ติดตั้งใหม่มีเพียง
เปิดใช้งานหลังจากรีบูต
ข้อกำหนดของเคอร์เนล
Linux ต่อไปนี้เพื่อรองรับโมดูลหลัก APEX บนอุปกรณ์ Android ต้องมีฟีเจอร์เคอร์เนล: ไดรเวอร์ Loopback และ dm-verity Loopback ไดรเวอร์จะต่อเชื่อมอิมเมจระบบไฟล์ในโมดูล APEX และยืนยันความถูกต้องของ โมดูล APEX
ประสิทธิภาพของตัวขับ Loopback และ dm-verity เป็นสิ่งสำคัญในการบรรลุผล ระบบมีประสิทธิภาพที่ดีเมื่อใช้โมดูล APEX
เวอร์ชันเคอร์เนลที่รองรับ
โมดูลหลัก APEX ได้รับการสนับสนุนในอุปกรณ์ที่ใช้เคอร์เนลเวอร์ชัน 4.4 หรือ สูงขึ้น อุปกรณ์ใหม่ที่จะเปิดตัวโดยใช้ Android 10 ขึ้นไป ต้องใช้เคอร์เนลเวอร์ชัน 4.9 ขึ้นไปเพื่อรองรับโมดูล APEX
แพตช์ของเคอร์เนลที่จำเป็น
แพตช์เคอร์เนลที่จำเป็นสำหรับการรองรับโมดูล APEX จะรวมอยู่ใน แผนผัง Android Common ในการรับแพตช์เพื่อรองรับ APEX โปรดใช้เวอร์ชันล่าสุด ของ Android Common
Kernel เวอร์ชัน 4.4
เวอร์ชันนี้รองรับเฉพาะอุปกรณ์ที่อัปเกรดจาก Android 9 เป็น
Android 10 และต้องการรองรับโมดูล APEX หากต้องการดาวน์โหลด
จำเป็นต้องอัปเดตแพตช์ การรวมดาวน์จาก Branch ของ android-4.4
แนะนำ รายการแพตช์ที่จำเป็นแต่ละรายการมีดังนี้
สำหรับเคอร์เนลเวอร์ชัน 4.4
- UPSTREAM: ลูป: เพิ่ม ioctl สำหรับการเปลี่ยนขนาดบล็อกเชิงตรรกะ (4.4)
- BACKPORT: บล็อก/ลูป: ตั้งค่า hw_sectors (4.4)
- UPSTREAM: ลูป: เพิ่ม LOOP_SET_BLOCK_SIZE ใน ioctl ที่ใช้ร่วมกัน (4.4)
- ANDROID: mnt: แก้ไข next_descendent (4.4)
- ANDROID: mnt: การต่อเชื่อมใหม่ควรเผยแพร่ไปยังทาสของทาส (4.4)
- ANDROID: mnt: เผยแพร่การติดตั้งใหม่อย่างถูกต้อง (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 โปรดตรวจสอบว่าพารามิเตอร์บรรทัดคำสั่งของเคอร์เนลเป็นไปตามข้อกำหนดต่อไปนี้ ข้อกำหนด
- ต้องไม่ตั้งค่า
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 |
ทรัพยากร Dependency แบบทรานซิทีฟ
ไฟล์ APEX จะรวมทรัพยากร Dependency แบบทรานซิทีฟของไลบรารีที่แชร์แบบเนทีฟโดยอัตโนมัติ
หรือไฟล์ปฏิบัติการ ตัวอย่างเช่น ถ้า libFoo
ขึ้นอยู่กับ libBar
ไลบรารี 2 อันจะเป็น
รวมเมื่อมีเพียง libFoo
เท่านั้นที่ปรากฏในพร็อพเพอร์ตี้ native_shared_libs
จัดการ ABI หลายรายการ
ติดตั้งพร็อพเพอร์ตี้ native_shared_libs
สำหรับทั้งหลักและรอง
อินเทอร์เฟซไบนารีของแอปพลิเคชัน (ABI) ของอุปกรณ์ หาก APEX กำหนดเป้าหมายอุปกรณ์
ที่มี ABI เดียว (ซึ่งก็คือ 32 บิตเท่านั้น หรือ 64 บิตเท่านั้น) เฉพาะไลบรารีที่มี
ติดตั้ง ABI ที่เกี่ยวข้องแล้ว
ติดตั้งพร็อพเพอร์ตี้ binaries
สำหรับ ABI หลักของอุปกรณ์เท่านั้นตามที่
ที่อธิบายไว้ด้านล่าง
- หากอุปกรณ์เป็นแบบ 32 บิตเท่านั้น เฉพาะไบนารี 32 บิตจะเป็น ติดตั้งไว้แล้ว
- หากอุปกรณ์เป็นแบบ 64 บิตเท่านั้น ไบนารี 64 บิตเท่านั้นจะเป็น ติดตั้งไว้แล้ว
วิธีเพิ่มการควบคุม ABI ของไลบรารีและไบนารีแบบเนทีฟโดยละเอียด
ให้ใช้
multilib.[first|lib32|lib64|prefer32|both].[native_shared_libs|binaries]
พร็อพเพอร์ตี้
first
: จับคู่ ABI หลักของอุปกรณ์ ตัวเลือกนี้เป็นค่าเริ่มต้นสำหรับ ไบนารีlib32
: จับคู่ ABI 32 บิตของอุปกรณ์ หากรองรับlib64
: ตรงกับ ABI 64 บิตของอุปกรณ์ที่รองรับprefer32
: จับคู่ ABI 32 บิตของอุปกรณ์ หากรองรับ หาก ไม่รองรับ ABI 32 บิต ตรงกับ ABI 64 บิตboth
: ตรงกับ ABI ทั้ง 2 รายการ ตัวเลือกนี้เป็นค่าเริ่มต้นสำหรับ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 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", }
ในตัวอย่างข้างต้น ชื่อของคีย์สาธารณะ (foo
) จะกลายเป็นรหัสของ
รหัสของคีย์ที่ใช้ในการลงนาม APEX จะเขียนอยู่ใน APEX ระหว่างรันไทม์
apexd
จะยืนยัน APEX โดยใช้คีย์สาธารณะที่มีรหัสเดียวกันในอุปกรณ์
การลงนาม APEX
รับรอง APEX ในลักษณะเดียวกันกับที่รับรอง APK ลงนาม APEXes 2 ครั้ง 1 ครั้งสำหรับ
ระบบไฟล์ขนาดเล็ก (apex_payload.img
ไฟล์) และครั้งเดียวสำหรับทั้งไฟล์
หากต้องการลงนาม APEX ที่ระดับไฟล์ ให้ตั้งค่าพร็อพเพอร์ตี้ certificate
ใน
3 วิธีต่อไปนี้
- ไม่ได้ตั้งค่า: หากไม่ได้ตั้งค่าไว้ ระบบจะลงชื่อ APEX ด้วยใบรับรองที่อยู่
ที่
PRODUCT_DEFAULT_DEV_CERTIFICATE
หากไม่ได้ตั้งค่า Flag ไว้ เส้นทางเริ่มต้น ไปยังbuild/target/product/security/testkey
<name>
: APEX ลงนามด้วยใบรับรอง<name>
เดียวกันกับ เป็นPRODUCT_DEFAULT_DEV_CERTIFICATE
:<name>
: APEX ลงนามด้วยใบรับรองที่กำหนดโดย โมดูล 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
หากตั้งค่า supportsRebootlessUpdate
เป็น true
ใน apex_manifest.json
และ
APEX ที่ติดตั้งอยู่ในปัจจุบันจะไม่มีการใช้งาน (เช่น บริการใดก็ตามที่อยู่ใน
) จากนั้น คุณสามารถติดตั้ง APEX ใหม่ได้โดยไม่ต้องรีบูตด้วย
แฟล็ก --force-non-staged
adb install --force-non-staged apex_file_name
ใช้ APEX
หลังจากรีบูต ระบบจะต่อเชื่อม APEX ไว้ที่ /apex/<apex_name>@<version>
ไดเรกทอรี คุณสามารถต่อเชื่อม APEX เดียวกันได้หลายเวอร์ชันพร้อมกัน
เส้นทางที่สอดคล้องกับเวอร์ชันล่าสุดในบรรดาเส้นทางต่อเชื่อมคือ
ต่อเชื่อมแบบต่อเชื่อมที่ /apex/<apex_name>
ไคลเอ็นต์สามารถใช้เส้นทางที่ผูกไว้เพื่ออ่านหรือเรียกใช้ไฟล์จาก APEX
โดยทั่วไป APEX จะมีการใช้งานดังนี้
- OEM หรือ ODM โหลด APEX ล่วงหน้าภายใต้
/system/apex
เมื่ออุปกรณ์ จัดส่งแล้ว - ไฟล์ใน APEX จะเข้าถึงได้ผ่านเส้นทาง
/apex/<apex_name>/
- เมื่อติดตั้ง APEX เวอร์ชันอัปเดตใน
/data/apex
แล้ว เส้นทาง ชี้ไปที่ APEX ใหม่หลังจากรีบูต
อัปเดตบริการด้วย APEX
วิธีอัปเดตบริการโดยใช้ APEX
ทำเครื่องหมายบริการในพาร์ติชันระบบเป็นอัปเดตได้ เพิ่มตัวเลือก
updatable
ไปยังคำจำกัดความของบริการ/system/etc/init/myservice.rc: service myservice /system/bin/myservice class core user system ... updatable
สร้างไฟล์
.rc
ใหม่สำหรับบริการที่อัปเดต ใช้ตัวเลือกoverride
เพื่อกำหนดบริการที่มีอยู่ใหม่/apex/my.apex/etc/init.rc: service myservice /apex/my.apex/bin/myservice class core user system ... override
คุณกำหนดคำจำกัดความของบริการได้ในไฟล์ .rc
ของ APEX เท่านั้น แอ็กชัน
ระบบไม่รองรับทริกเกอร์ใน APEXes
หากบริการที่ทำเครื่องหมายว่าสามารถอัปเดตได้เริ่มขึ้นก่อนที่จะเปิดใช้งาน 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
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 ที่ลงนามไว้ล่วงหน้าสำหรับ
โปรเจ็กต์ เช่น Mainline APEX ที่ไม่ได้ลงนามล่วงหน้า (สร้างขึ้นจาก
แหล่งที่มา) ก็ไม่ควรแยกเป็นหลายรายการและมีการรับรองด้วยคีย์ที่เหมาะสม
อุปกรณ์ควรรับค่าจาก updatable_apex.mk
ตามที่อธิบายไว้ใน
การอัปเดตบริการด้วย APEX
APEX ที่บีบอัด
Android 12 ขึ้นไปมีการบีบอัด APEX สำหรับ ซึ่งช่วยลดผลกระทบต่อพื้นที่เก็บข้อมูลของแพ็กเกจ APEX ที่อัปเดตได้ หลังการอัปเดตเป็น APEX แล้ว แม้จะไม่ได้ใช้เวอร์ชันที่ติดตั้งไว้ล่วงหน้าแล้วก็ตาม ยังใช้พื้นที่เท่าเดิม พื้นที่ที่มีการใช้งานนั้นยังคงไม่สามารถใช้ได้
การบีบอัด APEX ลดผลกระทบของพื้นที่เก็บข้อมูลลงโดยใช้ชุดที่มีการบีบอัดสูง
ของไฟล์ APEX ในพาร์ติชันแบบอ่านอย่างเดียว (เช่น พาร์ติชัน /system
) Android
12 ขึ้นไปใช้อัลกอริทึมการบีบอัดไฟล์ Zip DEFLATE
การบีบอัดไม่มีการเพิ่มประสิทธิภาพสำหรับสิ่งต่อไปนี้
APEX ของ Bootstrap ที่ต้องติดตั้งตั้งแต่เนิ่นๆ ในการเปิดเครื่อง ตามลำดับ
APEXes ที่ไม่สามารถอัปเดตได้ การบีบอัดจะมีประโยชน์เฉพาะในกรณีที่ติดตั้ง APEX เวอร์ชันที่อัปเดตแล้วเท่านั้น ในพาร์ติชัน
/data
ดูรายการ APEX ที่อัปเดตทั้งหมดได้ใน ส่วนประกอบของระบบโมดูลAPEXes ไลบรารีที่ใช้ร่วมกันแบบไดนามิก เนื่องจาก
apexd
จะเปิดใช้งานทั้ง 2 เวอร์ชันเสมอ APEX ดังกล่าว (ติดตั้งล่วงหน้าและอัปเกรด) แล้วการบีบอัดไม่ได้เพิ่มคุณค่า
รูปแบบไฟล์ APEX ที่บีบอัด
นี่คือรูปแบบของไฟล์ APEX ที่บีบอัด
รูปที่ 2 รูปแบบไฟล์ APEX ที่บีบอัด
ที่ระดับบนสุด ไฟล์ APEX ที่บีบอัดคือไฟล์ ZIP ที่มีไฟล์ ไฟล์ apex ในรูปแบบย่อที่มีระดับการบีบอัด 9 และมีไฟล์อื่นๆ โดยไม่มีการบีบอัด
ไฟล์ APEX 1 ไฟล์ประกอบด้วยไฟล์ 4 ไฟล์ ดังนี้
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 ที่บีบอัด
สำหรับการทดลองในพื้นที่ คุณสามารถบังคับให้บิลด์บีบอัด APEX ได้โดยการตั้งค่า
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
- ไฟล์
original_apex
ภายใน/system/apex/com.android.foo.capex
คือ คลายการบีบอัดเป็น/data/apex/decompressed/com.android.foo@37.apex
- ดำเนินการ
restorecon /data/apex/decompressed/com.android.foo@37.apex
เพื่อ ให้ยืนยันว่ามีป้ายกำกับ SELinux ที่ถูกต้อง - ตรวจสอบการยืนยันใน
/data/apex/decompressed/com.android.foo@37.apex
เพื่อตรวจสอบความถูกต้อง:apexd
ตรวจสอบคีย์สาธารณะที่รวมไว้ในกลุ่ม/data/apex/decompressed/com.android.foo@37.apex
เพื่อยืนยันว่าค่าเท่ากัน กับชุดข้อมูลที่อยู่ใน/system/apex/com.android.foo.capex
- ไฟล์
/data/apex/decompressed/com.android.foo@37.apex
ลิงก์ถาวรกับ ไดเรกทอรี/data/apex/active/com.android.foo@37.apex
- ตรรกะการเปิดใช้งานปกติสำหรับไฟล์ APEX ที่ไม่ได้บีบอัดจะดำเนินการใน
/data/apex/active/com.android.foo@37.apex
การโต้ตอบกับ OTA
ไฟล์ APEX ที่บีบอัดจะมีผลต่อการนำส่งและแอปพลิเคชัน OTA ตั้งแต่ปี การอัปเดต OTA อาจมีไฟล์ APEX ที่บีบอัดโดยมีระดับเวอร์ชันสูงกว่า พื้นที่ว่างบางส่วนจะสำรองไว้มากกว่าจำนวนที่มีการใช้งานในอุปกรณ์ ก่อนรีบูตอุปกรณ์เพื่อให้การอัปเดต OTA มีผล
apexd
จะแสดง Binder API ทั้ง 2 รายการต่อไปนี้เพื่อรองรับระบบ OTA
calculateSizeForCompressedApex
- คำนวณขนาดที่ต้องใช้ในการขยาย ไฟล์ APEX ในแพ็กเกจ OTA ซึ่งใช้เพื่อยืนยันว่าอุปกรณ์มี เพียงพอก่อนที่จะดาวน์โหลด OTAreserveSpaceForCompressedApex
- จองพื้นที่ในดิสก์ไว้ใช้ในอนาคต โดยapexd
สำหรับการขยายไฟล์ APEX ที่บีบอัดภายในแพ็กเกจ OTA
ในกรณีของการอัปเดต A/B OTA จะมี apexd
พยายามคลายการบีบอัดใน
เป็นส่วนหนึ่งของกิจวัตร OTA หลังการติดตั้ง หากยกเลิกการบีบอัดไม่สำเร็จ
apexd
ดำเนินการคลายการบีบอัดระหว่างเปิดเครื่องที่ใช้ OTA
อัปเดต
ทางเลือกที่นำมาพิจารณาเมื่อพัฒนา APEX
ตัวเลือกบางส่วนที่ AOSP นำมาพิจารณาเมื่อออกแบบไฟล์ APEX มีดังนี้ รวมถึงเหตุผลที่รวมหรือยกเว้นไว้
ระบบการจัดการแพ็กเกจปกติ
รุ่น Linux มีระบบการจัดการแพ็กเกจ เช่น dpkg
และ rpm
ซึ่งทรงพลัง สมบูรณ์แบบ และคงทน แต่ไม่ได้หมายความว่า
ใช้กับ APEX เพราะไม่สามารถปกป้องพัสดุได้หลังจาก
ของคุณ การยืนยันจะดำเนินการเมื่อมีการติดตั้งแพ็กเกจเท่านั้น
ผู้โจมตีอาจทำลายความสมบูรณ์ของแพ็กเกจที่ติดตั้งไว้โดยที่ไม่มีใครสังเกตเห็น นี่คือ
การถดถอยสำหรับ Android ซึ่งเก็บคอมโพเนนต์ทั้งหมดของระบบไว้ในแบบอ่านอย่างเดียว
ระบบไฟล์ซึ่งมีความสมบูรณ์ได้รับการปกป้องโดย dm-verity ใน I/O ทุกครั้ง ช่วง
ห้ามมิให้มีการดัดแปลงส่วนประกอบของระบบหรือให้ตรวจพบได้
อุปกรณ์อาจปฏิเสธไม่ให้เปิดเครื่องได้หากถูกบุกรุก
dm-crypt สำหรับความสมบูรณ์
ไฟล์ในคอนเทนเนอร์ APEX มาจากพาร์ติชันในตัว (ตัวอย่างเช่น
/system
พาร์ติชัน) ที่มีการป้องกันด้วย dm-verity โดยที่การแก้ไข
ไม่อนุญาตให้ใช้ไฟล์แม้ว่าจะต่อเชื่อมพาร์ติชันแล้วก็ตาม หากต้องการจัดเตรียม
ความปลอดภัยระดับเดียวกับไฟล์ โดยไฟล์ทั้งหมดใน APEX จะเก็บอยู่ในไฟล์
อิมเมจระบบที่จับคู่กับแผนผังแฮชและข้อบ่งชี้ vbmeta ไม่มี
dm-verity ซึ่ง APEX ในพาร์ติชัน /data
มีช่องโหว่ที่ไม่ได้ตั้งใจ
การเปลี่ยนแปลงที่เกิดขึ้นหลังจากได้รับการยืนยันและติดตั้งแล้ว
ที่จริงแล้ว พาร์ติชัน /data
ยังได้รับการปกป้องโดยเลเยอร์การเข้ารหัสอีกด้วย เช่น
dm-crypt แม้ว่าวิธีนี้จะช่วยป้องกันการปลอมแปลงได้ในระดับหนึ่ง
จุดประสงค์หลักคือความเป็นส่วนตัว ไม่ใช่ความซื่อสัตย์ เมื่อผู้โจมตีได้รับสิทธิ์เข้าถึง
/data
จะไม่มีการป้องกันใดๆ เพิ่มเติม และนี่ก็เป็น
การถดถอยเมื่อเทียบกับคอมโพเนนต์ทั้งหมดของระบบที่อยู่ในพาร์ติชัน /system
แผนผังแฮชภายในไฟล์ APEX ร่วมกับ dm-verity ให้
ระดับการปกป้องเนื้อหาได้
เปลี่ยนเส้นทางจาก /system ไปยัง /apex
ไฟล์คอมโพเนนต์ของระบบที่รวมอยู่ใน APEX จะสามารถเข้าถึงได้ผ่านเส้นทางใหม่ เช่น
/apex/<name>/lib/libfoo.so
เมื่อไฟล์ดังกล่าวเป็นส่วนหนึ่งของ /system
เข้าถึงได้โดยใช้เส้นทาง เช่น /system/lib/libfoo.so
ต
ของไฟล์ APEX (ไฟล์ APEX อื่นๆ หรือแพลตฟอร์ม) ต้องใช้
เส้นทาง คุณอาจต้องอัปเดตโค้ดที่มีอยู่เนื่องจากมีการเปลี่ยนเส้นทาง
แม้ว่าวิธีหนึ่งในการหลีกเลี่ยงการเปลี่ยนเส้นทางได้คือการซ้อนทับเนื้อหาของไฟล์ใน
ทีม Android ตัดสินใจที่จะไม่วางซ้อนไฟล์ APEX ลงในพาร์ติชัน /system
ในพาร์ติชัน /system
เนื่องจากอาจส่งผลต่อประสิทธิภาพ
จำนวนไฟล์ที่วางซ้อน (อาจวางซ้อนกัน)
เพิ่มขึ้น
อีกตัวเลือกหนึ่งคือการลักลอบใช้ฟังก์ชันการเข้าถึงไฟล์ เช่น open
, stat
และ
readlink
เพื่อให้เส้นทางที่ขึ้นต้นด้วย /system
ถูกเปลี่ยนเส้นทางไปยัง
เส้นทางที่เกี่ยวข้องใน /apex
ทีม Android ยกเลิกตัวเลือกนี้แล้ว
เนื่องจากคุณจะไม่สามารถเปลี่ยนฟังก์ชันทั้งหมดที่ยอมรับเส้นทาง
ตัวอย่างเช่น แอปบางแอปลิงก์ Bionic ในเชิงสถิติ ซึ่งจะใช้ฟังก์ชันต่างๆ
ในกรณีดังกล่าว แอปเหล่านั้นจะไม่ถูกเปลี่ยนเส้นทาง