ใน Android 10 ระบบไฟล์รูทจะไม่อยู่ใน ramdisk.img อีกต่อไป แต่จะผสานรวมกับ system.img แทน (กล่าวคือ system.img จะสร้างขึ้นเสมอหากตั้งค่า BOARD_BUILD_SYSTEM_ROOT_IMAGE ไว้) อุปกรณ์ที่เปิดตัวพร้อม Android 10
- ใช้เลย์เอาต์พาร์ติชันระบบเป็นรูท (บังคับใช้โดยอัตโนมัติโดย บิลด์โดยไม่มีตัวเลือกในการเปลี่ยนลักษณะการทำงาน)
- ต้องใช้ Ramdisk ซึ่งจำเป็นสำหรับ dm-linear
- ต้องตั้งค่า
BOARD_BUILD_SYSTEM_ROOT_IMAGEเป็นfalseการตั้งค่านี้ใช้เพื่อแยกความแตกต่างระหว่างอุปกรณ์ที่ใช้ Ramdisk กับอุปกรณ์ที่ไม่ได้ใช้ Ramdisk (และติดตั้งsystem.imgโดยตรงแทน) เท่านั้น
ความหมายของการกำหนดค่าระบบเป็นรูทจะแตกต่างกันระหว่าง Android 9 กับ
Android 10 ในการกำหนดค่าระบบเป็นรูทใน Android 9
ระบบจะตั้งค่า BOARD_BUILD_SYSTEM_ROOT_IMAGE เป็น
true ซึ่งบังคับให้บิลด์ผสานระบบไฟล์รูทเข้ากับ
system.img จากนั้นต่อเชื่อม system.img เป็นระบบไฟล์รูท (rootfs) การกำหนดค่านี้จำเป็นสำหรับอุปกรณ์ที่เปิดตัวด้วย Android 9 แต่ไม่บังคับสำหรับอุปกรณ์ที่อัปเกรดเป็น Android 9 และสำหรับอุปกรณ์ที่ใช้ Android เวอร์ชันต่ำกว่า ในการกำหนดค่าระบบเป็นรูทของ Android 10 บิลด์จะผสาน $TARGET_SYSTEM_OUT และ $TARGET_ROOT_OUT เข้ากับ system.img เสมอ การกำหนดค่านี้เป็นลักษณะการทำงานเริ่มต้นสำหรับอุปกรณ์ทั้งหมดที่ใช้ Android 10
Android 10 มีการเปลี่ยนแปลงเพิ่มเติมเพื่อรองรับพาร์ติชันแบบไดนามิก ซึ่งเป็นระบบการแบ่งพาร์ติชันในพื้นที่ผู้ใช้ที่ช่วยให้การอัปเดตผ่านอากาศ (OTA) สามารถ สร้าง ปรับขนาด หรือทำลายพาร์ติชันได้ การเปลี่ยนแปลงนี้ทำให้เคอร์เนล Linux ไม่สามารถติดตั้งพาร์ติชันระบบเชิงตรรกะในอุปกรณ์ที่ใช้ Android 10 ได้อีกต่อไป ดังนั้นการดำเนินการนี้จึงได้รับการจัดการโดย init ในระยะแรก
ส่วนต่อไปนี้จะอธิบายข้อกำหนดของระบบเป็นรูทสำหรับ OTA ของระบบเท่านั้น ให้คำแนะนำเกี่ยวกับการอัปเดตอุปกรณ์ให้ใช้ระบบเป็นรูท (รวมถึงการเปลี่ยนแปลงเลย์เอาต์พาร์ติชันและข้อกำหนดของเคอร์เนล dm-verity) ดูรายละเอียดเกี่ยวกับการเปลี่ยนแปลง ramdisk ได้ที่พาร์ติชัน Ramdisk
เกี่ยวกับการอัปเดต OTA ของระบบเท่านั้น
OTA ของระบบเท่านั้น ซึ่งช่วยให้รุ่น Android อัปเดต system.img และ product.img ได้โดยไม่ต้องเปลี่ยนพาร์ติชันอื่นๆ
ต้องใช้เลย์เอาต์พาร์ติชันระบบเป็นรูท อุปกรณ์ทั้งหมดที่ใช้ Android
10 ต้องใช้เลย์เอาต์พาร์ติชันระบบเป็นรูทเพื่อ
เปิดใช้ OTA ของระบบเท่านั้น
- อุปกรณ์ A/B ซึ่งติดตั้งพาร์ติชัน
systemเป็น rootfs ใช้ระบบเป็นรูทอยู่แล้วและไม่จำเป็นต้องเปลี่ยนแปลงเพื่อรองรับ OTA ของระบบ - อุปกรณ์ที่ไม่ใช่ A/B ซึ่งติดตั้งพาร์ติชัน
systemที่/systemต้องอัปเดตเพื่อใช้ เลย์เอาต์พาร์ติชันระบบเป็นรูทเพื่อรองรับ OTA ของระบบ
ดูรายละเอียดเกี่ยวกับอุปกรณ์ A/B และอุปกรณ์ที่ไม่ใช่ A/B ได้ที่ การอัปเดตระบบ A/B (แบบไร้รอยต่อ)
ใช้การซ้อนทับของผู้ให้บริการ (<=AOSP 14)
การวางซ้อนของผู้ให้บริการช่วยให้คุณวางซ้อนการเปลี่ยนแปลงในvendor
พาร์ติชันได้ในเวลาที่บูตอุปกรณ์ การวางซ้อนของผู้ให้บริการคือชุดโมดูลของผู้ให้บริการในพาร์ติชัน product ที่วางซ้อนบนพาร์ติชัน vendor
เมื่ออุปกรณ์บูต โดยจะแทนที่และเพิ่มลงในโมดูลที่มีอยู่
เมื่ออุปกรณ์บูต กระบวนการ init จะทำการติดตั้งในระยะแรกให้เสร็จสมบูรณ์และอ่านพร็อพเพอร์ตี้เริ่มต้น จากนั้นจะค้นหา
/product/vendor_overlay/<target_vendor_version>และเมานต์
แต่ละไดเรกทอรีย่อยในไดเรกทอรีพาร์ติชัน vendor ที่เกี่ยวข้อง
หากเป็นไปตามเงื่อนไขต่อไปนี้
- มี
/vendor/<overlay_dir>อยู่แล้ว /product/vendor_overlay/<target_vendor_version>/<overlay_dir>มีบริบทไฟล์เดียวกับ/vendor/<overlay_dir>initได้รับอนุญาตให้ติดตั้งในบริบทของไฟล์/vendor/<overlay_dir>
ใช้การวางซ้อนของผู้ให้บริการ
ติดตั้งไฟล์การวางซ้อนของผู้ให้บริการใน
/product/vendor_overlay/<target_vendor_version> ไฟล์เหล่านั้นจะซ้อนทับพาร์ติชัน vendor เมื่ออุปกรณ์เริ่มระบบ โดยจะแทนที่ไฟล์ที่มีชื่อเดียวกันและเพิ่มไฟล์ใหม่ Vendor Overlay ไม่สามารถนำไฟล์ออกจากพาร์ติชัน vendor ได้
ไฟล์วางซ้อนของผู้ให้บริการต้องมีบริบทไฟล์เหมือนกับไฟล์เป้าหมาย
ที่แทนที่ในพาร์ติชัน vendor โดยค่าเริ่มต้น ไฟล์ในไดเรกทอรี
/product/vendor_overlay/<target_vendor_version>
จะมีบริบท vendor_file หากบริบทของไฟล์ไม่ตรงกัน
ระหว่างไฟล์การวางซ้อนของผู้ให้บริการกับไฟล์ที่แทนที่ ให้ระบุใน
sepolicy เฉพาะอุปกรณ์ บริบทของไฟล์จะกำหนดที่ระดับไดเรกทอรี หากบริบทของไฟล์ในไดเรกทอรีการวางซ้อนของผู้ให้บริการไม่ตรงกับไดเรกทอรีเป้าหมาย
และไม่ได้ระบุบริบทของไฟล์ที่ถูกต้องใน sepolicy เฉพาะอุปกรณ์
ระบบจะไม่วางซ้อนไดเรกทอรีการวางซ้อนของผู้ให้บริการนั้นลงในไดเรกทอรีเป้าหมาย
หากต้องการใช้การวางซ้อนของผู้ให้บริการ เคอร์เนลต้องเปิดใช้ OverlayFS โดยการตั้งค่า
CONFIG_OVERLAY_FS=y นอกจากนี้ ต้องผสานเคอร์เนลจาก
เคอร์เนลทั่วไป 4.4 ขึ้นไป หรือแพตช์ด้วย "overlayfs:
override_creds=off option bypass creator_cred"
ตัวอย่างการติดตั้งใช้งานการวางซ้อนของผู้ให้บริการ
ขั้นตอนนี้แสดงการติดตั้งใช้งานการวางซ้อนของผู้ให้บริการที่วางซ้อนไดเรกทอรี /vendor/lib/*, /vendor/etc/* และ /vendor/app/*
-
เพิ่มไฟล์ของผู้ให้บริการที่สร้างไว้ล่วงหน้าใน
device/<vendor>/<target>/vendor_overlay/<target_vendor_version>/device/google/device/vendor_overlay/28/lib/libfoo.so device/google/device/vendor_overlay/28/lib/libbar.so device/google/device/vendor_overlay/28/etc/baz.xml device/google/device/vendor_overlay/28/app/qux.apk
-
ติดตั้งไฟล์ของผู้ให้บริการที่สร้างไว้ล่วงหน้าใน
product/vendor_overlayในdevice/google/device/device.mkPRODUCT_COPY_FILES += \ $(call find-copy-subdir-files,*,device/google/device/vendor_overlay,$(TARGET_COPY_OUT_PRODUCT)/vendor_overlay)
-
กำหนดบริบทของไฟล์หากไฟล์พาร์ติชัน
vendorเป้าหมายมีบริบทอื่นนอกเหนือจากvendor_fileเนื่องจาก/vendor/lib/*ใช้บริบทvendor_fileตัวอย่างนี้จึงไม่มีไดเรกทอรีดังกล่าวเพิ่มรายการต่อไปนี้ไปยัง
device/google/device-sepolicy/private/file_contexts/(product|system/product)/vendor_overlay/[0-9]+/etc(/.*)? u:object_r:vendor_configs_file:s0 /(product|system/product)/vendor_overlay/[0-9]+/app(/.*)? u:object_r:vendor_app_file:s0
-
อนุญาตให้
initกระบวนการติดตั้งการวางซ้อนของผู้ให้บริการในไฟล์ บริบทอื่นๆ นอกเหนือจากvendor_fileเนื่องจากinitกระบวนการมีสิทธิ์ติดตั้งในบริบทvendor_fileอยู่แล้ว ตัวอย่างนี้จึงไม่ได้กำหนดนโยบายสำหรับvendor_fileเพิ่มรายการต่อไปนี้ไปยัง
device/google/device-sepolicy/public/init.teallow init vendor_configs_file:dir mounton; allow init vendor_app_file:dir mounton;
ตรวจสอบความถูกต้องของการวางซ้อนของผู้ให้บริการ
หากต้องการตรวจสอบการกำหนดค่าการวางซ้อนของผู้ให้บริการ ให้เพิ่มไฟล์ใน
/product/vendor_overlay/<target_vendor_version>/<overlay_dir>
และตรวจสอบว่าไฟล์วางซ้อนบนไฟล์ใน
/vendor/<overlay_dir>หรือไม่
สำหรับบิลด์ userdebug จะมีโมดูลทดสอบสำหรับ Atest ดังนี้
$ atest -v fs_mgr_vendor_overlay_test
อัปเดตเป็นระบบเป็นรูท
หากต้องการอัปเดตอุปกรณ์ที่ไม่ใช่ A/B ให้ใช้ system-as-root คุณต้องอัปเดต
รูปแบบการแบ่งพาร์ติชันสำหรับ boot.img และ system.img ตั้งค่า
dm-verity และนำการขึ้นต่อกันในการบูตในรูทเฉพาะอุปกรณ์
ออก
อัปเดตพาร์ติชัน
อุปกรณ์ที่ไม่ใช่ A/B ต้องเก็บพาร์ติชัน /recovery แยกไว้เนื่องจากไม่มีพาร์ติชันสล็อตสำรอง (เช่น จาก boot_a เป็น boot_b) ซึ่งต่างจากอุปกรณ์ A/B ที่ใช้ /boot เป็นพาร์ติชันการกู้คืน
หากนำ /recovery ออกจากอุปกรณ์ที่ไม่ใช่ A/B และทำให้คล้ายกับรูปแบบ A/B โหมดการกู้คืน
อาจใช้งานไม่ได้ในระหว่างการอัปเดตพาร์ติชัน /boot ที่ล้มเหลว ด้วยเหตุนี้ พาร์ติชัน /recovery ต้องเป็นพาร์ติชันแยกจาก /boot สำหรับอุปกรณ์ที่ไม่ใช่ A/B ซึ่งหมายความว่าระบบจะอัปเดตอิมเมจการกู้คืนต่อไปในลักษณะที่เลื่อนออกไป (กล่าวคือ เหมือนกับในอุปกรณ์ที่ใช้ Android 8.1.0 หรือต่ำกว่า)
ตารางต่อไปนี้แสดงความแตกต่างของการแบ่งพาร์ติชันรูปภาพสำหรับอุปกรณ์ที่ไม่ใช่ A/B ก่อนและหลัง Android 9
| รูปภาพ | Ramdisk (ก่อน Android 9) | System-as-root (หลังจาก Android 9) |
|---|---|---|
boot.img |
มีเคอร์เนลและramdisk.img:
ramdisk.img
-/
- init.rc
- init
- etc -> /system/etc
- system/ (mount point)
- vendor/ (mount point)
- odm/ (mount point)
... |
มีเฉพาะเคอร์เนลการบูตปกติ |
recovery.img |
มีเคอร์เนลการกู้คืนและ
ramdisk.imgการกู้คืน |
|
system.img |
ประกอบด้วยข้อมูลต่อไปนี้
system.img
-/
- bin/
- etc
- vendor -> /vendor
- ... |
มีเนื้อหาที่ผสานจากต้นฉบับ system.img และ
ramdisk.img:
system.img
-/
- init.rc
- init
- etc -> /system/etc
- system/
- bin/
- etc/
- vendor -> /vendor
- ...
- vendor/ (mount point)
- odm/ (mount point)
... |
พาร์ติชันเองจะไม่เปลี่ยนแปลง ทั้ง ramdisk และ system-as-root ใช้รูปแบบพาร์ติชันต่อไปนี้
/boot/system/system/recovery/vendorฯลฯ
ตั้งค่า dm-verity
ในระบบเป็นรูท เคอร์เนลต้องต่อเชื่อม system.img ภายใต้
/ (จุดต่อเชื่อม) ด้วย
dm-verity AOSP รองรับการใช้งาน dm-verity
ต่อไปนี้สำหรับ system.img
vboot 1.0
สำหรับ vboot 1.0 เคอร์เนลต้องแยกวิเคราะห์
ข้อมูลเมตาเฉพาะ Android
ใน
/system จากนั้นแปลงเป็น
พารามิเตอร์ dm-verity เพื่อตั้งค่า dm-verity (ต้องใช้แพตช์เคอร์เนลเหล่านี้)
ตัวอย่างต่อไปนี้แสดงการตั้งค่าที่เกี่ยวข้องกับ dm-verity สำหรับ system-as-root ในบรรทัดคำสั่งเคอร์เนล
ro root=/dev/dm-0 rootwait skip_initramfs init=/init dm="system none ro,0 1 android-verity /dev/sda34" veritykeyid=id:7e4333f9bba00adfe0ede979e28ed1920492b40f
vboot 2.0
สำหรับ vboot 2.0
(AVB) Bootloader ต้องผสานรวม
external/avb/libavb ซึ่งจะแยกวิเคราะห์
ตัวอธิบาย hashtree สำหรับ /system แปลงเป็น
พารามิเตอร์ dm-verity และสุดท้ายส่งพารามิเตอร์ไปยัง
เคอร์เนลผ่านบรรทัดคำสั่งของเคอร์เนล (คำอธิบาย Hashtree ของ /system
อาจอยู่ใน /vbmeta หรือใน /system เอง)
vboot 2.0 ต้องใช้แพตช์เคอร์เนลต่อไปนี้
- https://android-review.googlesource.com/#/c/kernel/common/+/158491/
- แพตช์เคอร์เนล 4.4 แพตช์เคอร์เนล 4.9 ฯลฯ
ตัวอย่างต่อไปนี้แสดงการตั้งค่าที่เกี่ยวข้องกับ dm-verity สำหรับ system-as-root ในบรรทัดคำสั่งเคอร์เนล
ro root=/dev/dm-0 rootwait skip_initramfs init=/init dm="1 vroot none ro 1,0 5159992 verity 1 PARTUUID=00000016-0000-0000-0000-000000000000 PARTUUID=00000016-0000-0000-0000-000000000000 4096 4096 644999 644999 sha1 d80b4a8be3b58a8ab86fad1b498640892d4843a2 8d08feed2f55c418fb63447fec0d32b1b107e42c 10 restart_on_corruption ignore_zero_blocks use_fec_from_device PARTUUID=00000016-0000-0000-0000-000000000000 fec_roots 2 fec_blocks 650080 fec_start 650080"
ใช้โฟลเดอร์รูทเฉพาะอุปกรณ์
เมื่อใช้ระบบเป็นรูท หลังจากที่แฟลชGeneric System Image
(GSI) ในอุปกรณ์ (และก่อนที่จะเรียกใช้การทดสอบ
Vendor Test Suite) โฟลเดอร์รูทเฉพาะอุปกรณ์
ที่เพิ่มด้วย BOARD_ROOT_EXTRA_FOLDERS จะหายไปเนื่องจากเนื้อหาไดเรกทอรีรูททั้งหมด
ถูกแทนที่ด้วย GSI ของระบบเป็นรูท การนำโฟลเดอร์เหล่านี้ออกอาจทำให้อุปกรณ์
บูตไม่ได้หากมีการอ้างอิงทรัพยากร Dependency บนโฟลเดอร์รูทเฉพาะอุปกรณ์
(เช่น ใช้เป็นจุดต่อเชื่อม)
หากต้องการหลีกเลี่ยงปัญหานี้ อย่าใช้ BOARD_ROOT_EXTRA_FOLDERS เพื่อ
เพิ่มโฟลเดอร์รูทเฉพาะอุปกรณ์ หากต้องการระบุจุดเชื่อมต่อเฉพาะอุปกรณ์ ให้ใช้ /mnt/vendor/<mount point> (เพิ่มในบันทึกการเปลี่ยนแปลงเหล่านี้) ระบุจุดติดตั้งเฉพาะผู้ให้บริการเหล่านี้ได้
โดยตรงทั้งในfstab แผนผังอุปกรณ์ (สำหรับการติดตั้งในระยะแรก)
และไฟล์ /vendor/etc/fstab.{ro.hardware} โดยไม่ต้องตั้งค่าเพิ่มเติม (เนื่องจาก fs_mgr จะสร้างจุดติดตั้งเหล่านี้ภายใต้
/mnt/vendor/* โดยอัตโนมัติ)