ใน Android 10 ระบบไฟล์รูทจะใช้ไม่ได้อีกต่อไป
ซึ่งรวมอยู่ใน ramdisk.img
และรวมเข้ากับ
system.img
(กล่าวคือ system.img
จะสร้างขึ้นเป็น
หากตั้งค่า BOARD_BUILD_SYSTEM_ROOT_IMAGE
ไว้) อุปกรณ์
ที่เปิดตัวพร้อม Android 10
- ใช้เลย์เอาต์พาร์ติชันของระบบระดับรูท (บังคับใช้โดยอัตโนมัติโดย สร้างโดยไม่มีตัวเลือกในการเปลี่ยนลักษณะการทำงาน)
- ต้องใช้ Ramdisk ซึ่งจำเป็นสำหรับ dm-Linear
- ต้องตั้งค่า
BOARD_BUILD_SYSTEM_ROOT_IMAGE
เป็นfalse
การตั้งค่านี้ใช้เพื่อแยกความแตกต่างระหว่างอุปกรณ์ที่ใช้ RAM เท่านั้น และอุปกรณ์ที่ไม่ใช้ 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 (ที่ราบรื่น)
ใช้การวางซ้อนผู้ให้บริการ
การวางซ้อนผู้ให้บริการช่วยให้คุณซ้อนทับการเปลี่ยนแปลงกับ 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
จะมีโมดูลทดสอบสำหรับ Atest:
$ atest -v fs_mgr_vendor_overlay_test
อัปเดตเป็นรูทของระบบ
หากต้องการอัปเดตอุปกรณ์ที่ไม่ใช่ A/B ให้ใช้ระบบที่เป็นรูท คุณต้องอัปเดต
รูปแบบการแบ่งพาร์ติชันสำหรับ boot.img
และ system.img
ตั้งค่าแล้ว
เพิ่มค่า dm-verity และลบการพึ่งพาการเปิดเครื่องในรูทเฉพาะอุปกรณ์
โฟลเดอร์
อัปเดตพาร์ติชัน
ซึ่งแตกต่างจากอุปกรณ์ A/B ที่เปลี่ยนวัตถุประสงค์การใช้งาน /boot
เป็น
พาร์ติชัน recovery
อุปกรณ์ที่ไม่ใช่ 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
รูปภาพ | Ramdisk (ก่อน 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 และการใช้งานในระบบเป็นรูท รูปแบบพาร์ติชันต่อไปนี้
/boot
/system
/system
/recovery
/vendor
ฯลฯ
ตั้งค่า DM-verity
ในรูทของระบบ เคอร์เนลต้องต่อเชื่อม system.img
ไว้ใต้
/
(จุดต่อเชื่อม) พร้อม
dm-verity AOSP รองรับ dm-verity ต่อไปนี้
การติดตั้งใช้งานสำหรับ system.img
vboot 1.0
สำหรับ vboot 1.0 เคอร์เนลจะต้องแยกวิเคราะห์
เฉพาะสำหรับ Android
metadata เปิดอยู่
/system
จากนั้นแปลงเป็น
พารามิเตอร์ dm-verity เพื่อตั้งค่า dm-verity (ต้องมี
แพตช์เคอร์เนลเหล่านี้)
ตัวอย่างต่อไปนี้แสดงการตั้งค่าที่เกี่ยวข้องกับ dm-verity สำหรับระดับรากของระบบ
บรรทัดคำสั่งเคอร์เนล:
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) ตัวโหลดบูทต้องผสานรวม
external/avb/libavb ซึ่งจะแยกวิเคราะห์ฟังก์ชัน
ข้อบ่งชี้แฮชทรีสำหรับ /system
, แปลง
เพื่อ
พารามิเตอร์ dm-verity และสุดท้ายจะส่งพารามิเตอร์ไปยัง
เคอร์เนลผ่านบรรทัดคำสั่งของเคอร์เนล (ข้อบ่งชี้แฮชทรีของ /system
อาจอยู่ใน /vbmeta
หรือ /system
เอง)
vboot 2.0 ต้องการแพตช์ของเคอร์เนลต่อไปนี้
- https://android-review.googlesource.com/#/c/kernel/common/+/158491/
- แพตช์ 4.4 เคอร์เนล เคอร์เนล 4.9 แพตช์ ฯลฯ
ตัวอย่างต่อไปนี้แสดงการตั้งค่าที่เกี่ยวข้องกับ dm-verity สำหรับระดับรากของระบบ บรรทัดคำสั่งเคอร์เนล:
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) กะพริบในอุปกรณ์ (และก่อนเรียกใช้
ชุดทดสอบของผู้ให้บริการ)
เพิ่มโฟลเดอร์รูทเฉพาะอุปกรณ์ด้วย BOARD_ROOT_EXTRA_FOLDERS
แล้ว
หายไปเนื่องจากเนื้อหาของไดเรกทอรีรากทั้งหมดถูกแทนที่โดย
GSI ของระบบในระดับราก การนำโฟลเดอร์เหล่านี้ออกอาจทำให้อุปกรณ์
บูตไม่ได้หากมีทรัพยากร Dependency ในโฟลเดอร์รูทเฉพาะอุปกรณ์อยู่
(เช่น ใช้เป็นจุดต่อเชื่อม)
หากไม่ต้องการให้เกิดปัญหานี้ โปรดอย่าใช้ BOARD_ROOT_EXTRA_FOLDERS
เพื่อ
เพิ่มโฟลเดอร์รูทเฉพาะอุปกรณ์ หากจำเป็นต้องระบุตัวยึดเฉพาะอุปกรณ์
ใช้ /mnt/vendor/<mount point>
(เพิ่มในรายการต่อไปนี้
changelists) จุดต่อเชื่อมเฉพาะผู้ให้บริการเหล่านี้อาจ
ที่ระบุโดยตรงในแผนผังอุปกรณ์ของ fstab
ทั้ง 2 โครงสร้าง (สำหรับระยะแรก
ต่อเชื่อม) และไฟล์ /vendor/etc/fstab.{ro.hardware}
ที่ไม่มี
การตั้งค่าเพิ่มเติม (เนื่องจาก fs_mgr
สร้างการตั้งค่าภายใต้
/mnt/vendor/*
โดยอัตโนมัติ)