ใน 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 ทำการเปลี่ยนแปลงเพิ่มเติมเพื่อรองรับ พาร์ติชันแบบไดนามิก ซึ่งเป็นระบบการแบ่งพาร์ติชันพื้นที่ผู้ใช้ที่เปิดใช้งานการอัปเดตแบบ over-the-air (OTA) เพื่อสร้าง ปรับขนาด หรือทำลายพาร์ติชัน ส่วนหนึ่งของการเปลี่ยนแปลงนี้ เคอร์เนล Linux ไม่สามารถเมานต์พาร์ติชันระบบแบบลอจิคัลบนอุปกรณ์ที่ใช้ Android 10 ได้อีกต่อไป ดังนั้นการดำเนินการนี้จะได้รับการจัดการโดย init ระยะแรก
ส่วนต่อไปนี้จะอธิบายข้อกำหนดของระบบในฐานะรูทสำหรับ OTA เฉพาะระบบ ให้คำแนะนำในการอัปเดตอุปกรณ์เพื่อใช้ระบบในฐานะรูท (รวมถึงการเปลี่ยนแปลงเค้าโครงพาร์ติชันและข้อกำหนดเคอร์เนล dm-verity) สำหรับรายละเอียดเกี่ยวกับการเปลี่ยนแปลง ramdisk โปรดดูที่ Ramdisk Partitions
เกี่ยวกับ OTA เฉพาะระบบ
OTA เฉพาะระบบ ซึ่งช่วยให้ Android รุ่นต่างๆ สามารถอัปเดต system.img
และ product.img
โดยไม่ต้องเปลี่ยนพาร์ติชั่นอื่นๆ จำเป็นต้องมีโครงร่างพาร์ติชั่นระบบเหมือนเป็นรูท อุปกรณ์ทั้งหมดที่ใช้ Android 10 ต้องใช้เค้าโครงพาร์ติชันระบบเป็นรูทเพื่อเปิดใช้งาน OTA เฉพาะระบบ
- อุปกรณ์ A/B ซึ่งติดตั้งพาร์ติชัน
system
เป็น rootfs ใช้ระบบเป็น root อยู่แล้ว และไม่จำเป็นต้องมีการเปลี่ยนแปลงเพื่อรองรับ OTA ของระบบ - อุปกรณ์ที่ไม่ใช่ A/B ซึ่งติดตั้งพาร์ติชัน
system
ที่/system
จะต้องได้รับ การอัปเดตเพื่อใช้โครงร่างพาร์ติชันระบบในฐานะรูท เพื่อรองรับ OTA ของระบบ
สำหรับรายละเอียดเกี่ยวกับอุปกรณ์ A/B และที่ไม่ใช่ A/B โปรดดู การอัปเดตระบบ A/B (ไร้รอยต่อ)
การใช้การซ้อนทับของผู้ขาย
การซ้อนทับของผู้จำหน่ายทำให้คุณสามารถโอเวอร์เลย์การเปลี่ยนแปลงไปยังพาร์ติชันของ 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
ได้
ไฟล์ซ้อนทับของผู้จัดจำหน่ายต้องมีบริบทของไฟล์เดียวกันกับไฟล์เป้าหมายที่จะแทนที่ในพาร์ติชัน 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.mk
:PRODUCT_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.te
:allow 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
builds มีโมดูลทดสอบสำหรับ Atest :
$ atest -v fs_mgr_vendor_overlay_test
กำลังอัปเดตเป็นระบบในฐานะรูท
หากต้องการอัปเดตอุปกรณ์ที่ไม่ใช่ A/B เพื่อใช้ระบบในฐานะรูท คุณต้องอัปเดตรูปแบบการแบ่งพาร์ติชันสำหรับ boot.img
และ system.img
ตั้งค่า dm-verity และลบการพึ่งพาการบูตใดๆ บนโฟลเดอร์รูทเฉพาะอุปกรณ์
กำลังอัปเดตพาร์ติชัน
ต่างจากอุปกรณ์ A/B ที่ปรับใช้ /boot
เป็นพาร์ติชั่ นการกู้คืน อุปกรณ์ที่ไม่ใช่ A/B จะต้องแยกพาร์ติชั่น /recovery
ออกจากกัน เนื่องจากไม่มีพาร์ติชั่นสล็อตทางเลือก (เช่น จาก boot_a
ถึง boot_b
) หาก /recovery
ถูกลบออกจากอุปกรณ์ที่ไม่ใช่ A/B และทำคล้ายกับรูปแบบ A/B โหมดการกู้คืนอาจหยุดทำงานในระหว่างการอัพเดตพาร์ติชั่น /boot
ที่ล้มเหลว ด้วยเหตุนี้ พาร์ติ /recovery
จะต้อง เป็นพาร์ติชันแยกต่างหากจาก /boot
สำหรับอุปกรณ์ที่ไม่ใช่ A/B ซึ่งหมายความว่าอิมเมจการกู้คืนจะได้รับการอัปเดตต่อไปในลักษณะที่เลื่อนออกไป (นั่นคือ เช่นเดียวกับในอุปกรณ์ที่ใช้ Android 8.1.0 หรือต่ำกว่า)
ตารางต่อไปนี้แสดงความแตกต่างของพาร์ติชันรูปภาพสำหรับอุปกรณ์ที่ไม่ใช่ A/B ก่อนและหลัง Android 9
ภาพ | แรมดิสก์ (ก่อน 9 โมง) | ระบบในฐานะรูท (หลัง 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-as-root เคอร์เนลจะต้องเมานต์ system.img
ภายใต้ /
(จุดเมานท์) ด้วย dm-verity AOSP รองรับการใช้งาน dm-verity ต่อไปนี้สำหรับ system.img
วีบูต 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
วีบูต 2.0
สำหรับ vboot 2.0 ( AVB ) บูตโหลดเดอร์จะต้องผสานรวม external/avb/libavb ซึ่งจะแยกวิเคราะห์ descriptor hashtree สำหรับ /system
แปลงเป็น dm-verity params และสุดท้ายก็ส่งพารามิเตอร์ไปยังเคอร์เนลผ่านบรรทัดคำสั่งเคอร์เนล (ตัวอธิบาย 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"
การใช้โฟลเดอร์รูทเฉพาะอุปกรณ์
เมื่อใช้ระบบในฐานะรูท หลังจากที่ อิมเมจระบบทั่วไป (GSI) ถูกแฟลชบนอุปกรณ์ (และก่อนที่จะรันการทดสอบ Vendor Test Suite ) โฟลเดอร์รูทเฉพาะอุปกรณ์ใดๆ ที่เพิ่มด้วย BOARD_ROOT_EXTRA_FOLDERS
จะหายไปเนื่องจากเนื้อหาไดเร็กทอรีรูททั้งหมดถูกแทนที่ โดยระบบ-as-root GSI การลบโฟลเดอร์เหล่านี้อาจทำให้อุปกรณ์ไม่สามารถบูตได้หากมีการพึ่งพาโฟลเดอร์รูทเฉพาะอุปกรณ์อยู่ (เช่น ใช้เป็นจุดต่อเชื่อม)
เพื่อหลีกเลี่ยงปัญหานี้ อย่าใช้ BOARD_ROOT_EXTRA_FOLDERS
เพื่อเพิ่มโฟลเดอร์รูทเฉพาะอุปกรณ์ หากคุณต้องการระบุจุดเชื่อมต่อเฉพาะอุปกรณ์ ให้ใช้ /mnt/vendor/<mount point>
(เพิ่มใน รายการการเปลี่ยนแปลง เหล่านี้) จุดเมานท์เฉพาะผู้จำหน่ายเหล่านี้สามารถระบุได้โดยตรงทั้งในแผนผังอุปกรณ์ fstab
(สำหรับการเมานต์ขั้นแรก) และไฟล์ /vendor/etc/fstab.{ro.hardware}
โดยไม่ต้องตั้งค่าเพิ่มเติม (เนื่องจาก fs_mgr
สร้างขึ้นภายใต้ /mnt/vendor/*
อัตโนมัติ)