การแบ่งพาร์ติชันแบบไดนามิกดำเนินการโดยใช้โมดูล dm-linear device-mapper ในเคอร์เนล Linux super
พาร์ติชั่นประกอบด้วยข้อมูลเมตาที่แสดงรายการชื่อและช่วงบล็อกของแต่ละพาร์ติชั่นไดนามิกภายใน super
ในระหว่างขั้นตอนแรก init
ข้อมูลเมตานี้จะถูกแยกวิเคราะห์และตรวจสอบ และอุปกรณ์บล็อกเสมือนจะถูกสร้างขึ้นเพื่อแสดงแต่ละพาร์ติชันแบบไดนามิก
เมื่อใช้ OTA พาร์ติชันแบบไดนามิกจะถูกสร้างขึ้น ปรับขนาด หรือลบโดยอัตโนมัติตามความจำเป็น สำหรับอุปกรณ์ A/B มีข้อมูลเมตาสองชุด และการเปลี่ยนแปลงจะมีผลกับสำเนาที่แสดงถึงช่องเป้าหมายเท่านั้น
เนื่องจากมีการใช้พาร์ติชั่นไดนามิกใน userspace พาร์ติชั่นที่ bootloader ต้องการจึงไม่สามารถทำให้เป็นไดนามิกได้ ตัวอย่างเช่น boot
, dtbo
และ vbmeta
จะถูกอ่านโดย bootloader และจะต้องยังคงเป็นฟิสิคัลพาร์ติชัน
ไดนามิกแต่ละพาร์ติชั่นสามารถอยู่ใน กลุ่มอัพเดต ได้ กลุ่มเหล่านี้จำกัดพื้นที่สูงสุดที่พาร์ติชันในกลุ่มนั้นสามารถใช้ได้ ตัวอย่างเช่น system
และ vendor
สามารถอยู่ในกลุ่มที่จำกัดขนาดรวมของ system
และ vendor
การใช้พาร์ติชั่นไดนามิกบนอุปกรณ์ใหม่
ส่วนนี้ให้รายละเอียดเกี่ยวกับวิธีการใช้พาร์ติชั่นไดนามิกบนอุปกรณ์ใหม่ที่เปิดตัวด้วย Android 10 ขึ้นไป ในการอัปเดตอุปกรณ์ที่มีอยู่ โปรดดูที่ การอัปเกรดอุปกรณ์ Android
การเปลี่ยนแปลงพาร์ทิชัน
สำหรับอุปกรณ์ที่เปิดตัวด้วย Android 10 ให้สร้างพาร์ติชั่นชื่อ super
. super
พาร์ติชั่นจัดการสล็อต A/B ภายใน ดังนั้นอุปกรณ์ A/B จึงไม่จำเป็นต้องมีพาร์ติชั่น super_a
และ super_b
แยกจากกัน พาร์ติชั่น AOSP แบบอ่านอย่างเดียวทั้งหมดที่ไม่ได้ใช้โดย bootloader ต้องเป็นไดนามิกและต้องถูกลบออกจาก GUID Partition Table (GPT) พาร์ติชั่นเฉพาะผู้จำหน่ายไม่จำเป็นต้องเป็นไดนามิกและอาจวางไว้ใน GPT
ในการประมาณขนาดของ super
ให้เพิ่มขนาดของพาร์ติชั่นที่กำลังลบออกจาก GPT สำหรับอุปกรณ์ A/B ควรรวมขนาดของช่องทั้งสองไว้ด้วย รูปที่ 1 แสดงตารางพาร์ติชั่นตัวอย่างก่อนและหลังการแปลงเป็นไดนามิกพาร์ติชั่น

พาร์ติชันไดนามิกที่รองรับคือ:
- ระบบ
- ผู้ขาย
- ผลิตภัณฑ์
- ต่อระบบ
- ODM
สำหรับอุปกรณ์ที่เปิดตัวด้วย Android 10 ตัวเลือกบรรทัดคำสั่งเคอร์เนล androidboot.super_partition
จะต้องว่างเปล่าเพื่อให้คำสั่ง sysprop ro.boot.super_partition
ว่างเปล่า
การจัดตำแหน่งพาร์ติชั่น
โมดูลตัวแมปอุปกรณ์อาจทำงานได้อย่างมีประสิทธิภาพน้อยลงหาก super
พาร์ติชั่นไม่ได้รับการจัดตำแหน่งอย่างเหมาะสม super
พาร์ติชั่นต้องจัดชิดกับ ขนาดคำขอ I/O ขั้นต่ำตาม ที่กำหนดโดยชั้นบล็อก ตามค่าดีฟอลต์ ระบบบิลด์ (ผ่าน lpmake
ซึ่งสร้างอิมเมจ super
พาร์ติชั่น) จะถือว่าการจัดตำแหน่ง 1 MiB นั้นเพียงพอสำหรับทุกพาร์ติชั่นไดนามิก อย่างไรก็ตาม ผู้ขายควรตรวจสอบให้แน่ใจว่า super
พาร์ติชันถูกจัดตำแหน่งอย่างเหมาะสม
คุณสามารถกำหนดขนาดคำขอขั้นต่ำของอุปกรณ์บล็อกได้โดยการตรวจสอบ sysfs
ตัวอย่างเช่น:
# ls -l /dev/block/by-name/super lrwxrwxrwx 1 root root 16 1970-04-05 01:41 /dev/block/by-name/super -> /dev/block/sda17 # cat /sys/block/sda/queue/minimum_io_size 786432
คุณสามารถตรวจสอบการจัดตำแหน่งของ super
partition ได้ในลักษณะเดียวกัน:
# cat /sys/block/sda/sda17/alignment_offset
ค่าชดเชยการจัดตำแหน่งต้องเป็น 0
การเปลี่ยนแปลงการกำหนดค่าอุปกรณ์
หากต้องการเปิดใช้งานการแบ่งพาร์ติชันแบบไดนามิก ให้เพิ่มแฟล็กต่อไปนี้ใน device.mk
:
PRODUCT_USE_DYNAMIC_PARTITIONS := true
การเปลี่ยนแปลงการกำหนดค่าบอร์ด
คุณต้องกำหนดขนาดของพาร์ติชัน super
:
BOARD_SUPER_PARTITION_SIZE := <size-in-bytes>
บนอุปกรณ์ A/B ระบบบิลด์จะแสดงข้อผิดพลาดหากขนาดรวมของอิมเมจพาร์ติชั่นไดนามิกมากกว่าครึ่งหนึ่งของขนาด super
พาร์ติชั่น
คุณสามารถกำหนดคอนฟิกรายการของไดนามิกพาร์ติชันดังต่อไปนี้ สำหรับอุปกรณ์ที่ใช้กลุ่มอัปเดต ให้ระบุกลุ่มในตัวแปร BOARD_SUPER_PARTITION_GROUPS
ชื่อกลุ่มแต่ละกลุ่มจะมี BOARD_ group _SIZE
และ BOARD_ group _PARTITION_LIST
สำหรับอุปกรณ์ A/B ขนาดสูงสุดของกลุ่มควรครอบคลุมเพียงช่องเดียว เนื่องจากชื่อกลุ่มจะต่อท้ายช่องภายใน
นี่คือตัวอย่างอุปกรณ์ที่วางพาร์ติชั่นทั้งหมดในกลุ่มที่เรียกว่า example_dynamic_partitions
:
BOARD_SUPER_PARTITION_GROUPS := example_dynamic_partitions BOARD_EXAMPLE_DYNAMIC_PARTITIONS_SIZE := 6442450944 BOARD_EXAMPLE_DYNAMIC_PARTITIONS_PARTITION_LIST := system vendor product
นี่คือตัวอย่างอุปกรณ์ที่วางระบบและผลิตภัณฑ์บริการไว้ใน group_foo
และ vendor
, product
และ odm
ลงใน group_bar
:
BOARD_SUPER_PARTITION_GROUPS := group_foo group_bar BOARD_GROUP_FOO_SIZE := 4831838208 BOARD_GROUP_FOO_PARTITION_LIST := system product_services BOARD_GROUP_BAR_SIZE := 1610612736 BOARD_GROUP_BAR_PARTITION_LIST := vendor product odm
- สำหรับอุปกรณ์เปิดใช้ A/B เสมือน ผลรวมของขนาดสูงสุดของทุกกลุ่มต้องไม่เกิน:
BOARD_SUPER_PARTITION_SIZE
- ค่าโสหุ้ย
ดู การใช้งาน Virtual A/B - สำหรับอุปกรณ์เปิดตัว A/B ผลรวมของขนาดสูงสุดของทุกกลุ่มต้องเป็น:
BOARD_SUPER_PARTITION_SIZE
/ 2 - ค่าโสหุ้ย - สำหรับอุปกรณ์ที่ไม่ใช่ A/B และอุปกรณ์ A/B ดัดแปลง ผลรวมของขนาดสูงสุดของทุกกลุ่มจะต้องเป็น:
BOARD_SUPER_PARTITION_SIZE
- ค่าโสหุ้ย - ณ เวลาบิลด์ ผลรวมของขนาดของอิมเมจของแต่ละพาร์ติชั่นในกลุ่มอัพเดตจะต้องไม่เกินขนาดสูงสุดของกลุ่ม
- ต้อง ใช้ค่าโสหุ้ย ในการคำนวณเพื่อพิจารณาข้อมูลเมตา การจัดตำแหน่ง และอื่นๆ ค่าโสหุ้ยที่สมเหตุสมผลคือ 4 MiB แต่คุณสามารถเลือกค่าโสหุ้ยที่ใหญ่กว่าได้ตามที่อุปกรณ์ต้องการ
การปรับขนาดพาร์ติชั่นไดนามิก
ก่อนพาร์ติชั่นไดนามิก ขนาดพาร์ติชั่นได้รับการจัดสรรเกินเพื่อให้แน่ใจว่ามีพื้นที่เพียงพอสำหรับการอัพเดตในอนาคต ขนาดจริงถูกนำมาใช้ตามที่เป็นอยู่และพาร์ติชั่นแบบอ่านอย่างเดียวส่วนใหญ่มีพื้นที่ว่างในระบบไฟล์บางส่วน ในไดนามิกพาร์ติชั่น พื้นที่ว่างนั้นใช้ไม่ได้และสามารถใช้เพื่อขยายพาร์ติชั่นระหว่าง OTA ได้ สิ่งสำคัญคือต้องตรวจสอบให้แน่ใจว่าพาร์ติชั่นไม่เปลืองพื้นที่และได้รับการจัดสรรให้มีขนาดต่ำสุดที่เป็นไปได้
สำหรับอิมเมจ ext4 แบบอ่านอย่างเดียว ระบบบิลด์จะจัดสรรขนาดต่ำสุดโดยอัตโนมัติหากไม่มีการระบุขนาดพาร์ติชั่นฮาร์ดโค้ด ระบบบิลด์จะพอดีกับอิมเมจเพื่อให้ระบบไฟล์มีพื้นที่ว่างที่ไม่ได้ใช้น้อยที่สุด เพื่อให้แน่ใจว่าอุปกรณ์จะไม่เปลืองพื้นที่ที่สามารถใช้สำหรับ OTA ได้
นอกจากนี้ อิมเมจ ext4 สามารถบีบอัดเพิ่มเติมได้โดยเปิดใช้งานการขจัดข้อมูลซ้ำซ้อนระดับบล็อก หากต้องการเปิดใช้งาน ให้ใช้การกำหนดค่าต่อไปนี้:
BOARD_EXT4_SHARE_DUP_BLOCKS := true
หากไม่ต้องการการจัดสรรขนาดพาร์ติชั่นขั้นต่ำโดยอัตโนมัติ มีสองวิธีในการควบคุมขนาดพาร์ติชั่น คุณสามารถระบุพื้นที่ว่างขั้นต่ำด้วย BOARD_ partition IMAGE_PARTITION_RESERVED_SIZE
หรือคุณสามารถระบุ BOARD_ partition IMAGE_PARTITION_SIZE
เพื่อบังคับให้พาร์ติชันแบบไดนามิกมีขนาดเฉพาะ ไม่แนะนำสิ่งเหล่านี้เว้นแต่จำเป็น
ตัวอย่างเช่น:
BOARD_PRODUCTIMAGE_PARTITION_RESERVED_SIZE := 52428800
สิ่งนี้บังคับให้ระบบไฟล์ใน product.img
มีพื้นที่ว่างที่ไม่ได้ใช้ 50 MiB
การเปลี่ยนแปลงระบบในฐานะรูท
อุปกรณ์ที่เปิดตัวด้วย Android 10 ต้องไม่ใช้ system-as-root
อุปกรณ์ที่มีพาร์ติชั่นไดนามิก (ไม่ว่าจะเปิดใช้หรือติดตั้งไดนามิกพาร์ติชั่นเพิ่มเติม) ต้องไม่ใช้ system-as-root เคอร์เนล Linux ไม่สามารถตีความ super
partition ดังนั้นจึงไม่สามารถเมานต์ system
ได้ ตอนนี้ system
ถูกติดตั้งโดยขั้นตอนแรก init
ซึ่งอยู่ใน ramdisk
อย่าตั้งค่า BOARD_BUILD_SYSTEM_ROOT_IMAGE
ใน Android 10 แฟ BOARD_BUILD_SYSTEM_ROOT_IMAGE
จะใช้เพื่อแยกความแตกต่างว่าระบบถูกเมาต์โดยเคอร์เนลหรือโดย init
ระยะแรกใน ramdisk เท่านั้น
การตั้งค่า BOARD_BUILD_SYSTEM_ROOT_IMAGE
true
จะทำให้เกิดข้อผิดพลาดในการสร้างเมื่อ PRODUCT_USE_DYNAMIC_PARTITIONS
เป็น true
ด้วย
เมื่อตั้งค่า BOARD_USES_RECOVERY_AS_BOOT
เป็นจริง อิมเมจการกู้คืนจะถูกสร้างขึ้นเป็น boot.img ซึ่งมี ramdisk ของการกู้คืน ก่อนหน้านี้ bootloader ใช้พารามิเตอร์บรรทัดคำสั่งเคอร์เนล skip_initramfs
เพื่อตัดสินใจว่าจะบูตเข้าสู่โหมดใด สำหรับอุปกรณ์ Android 10 นั้น bootloader ต้องไม่ส่ง skip_initramfs
ไปยังบรรทัดคำสั่งเคอร์เนล แต่ bootloader ควรผ่าน androidboot.force_normal_boot=1
เพื่อข้ามการกู้คืนและบูต Android ปกติ อุปกรณ์ที่เปิดตัวด้วย Android 12 หรือใหม่กว่าต้องใช้ bootconfig เพื่อส่งผ่าน androidboot.force_normal_boot=1
การเปลี่ยนแปลงการกำหนดค่า AVB
เมื่อใช้ Android Verified Boot 2.0 หากอุปกรณ์ไม่ได้ใช้ ตัวอธิบายพาร์ติชันที่ถูกล่ามโซ่ ก็ไม่ต้องทำการเปลี่ยนแปลงใดๆ อย่างไรก็ตาม หากใช้พาร์ติชั่นลูกโซ่ และหนึ่งในพาร์ติชั่นที่ตรวจสอบแล้วเป็นไดนามิก การเปลี่ยนแปลงนั้นจำเป็น
นี่คือตัวอย่างการกำหนดค่าสำหรับอุปกรณ์ที่ vbmeta
สำหรับพาร์ติชัน system
และ vendor
BOARD_AVB_SYSTEM_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem BOARD_AVB_SYSTEM_ALGORITHM := SHA256_RSA2048 BOARD_AVB_SYSTEM_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP) BOARD_AVB_SYSTEM_ROLLBACK_INDEX_LOCATION := 1 BOARD_AVB_VENDOR_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem BOARD_AVB_VENDOR_ALGORITHM := SHA256_RSA2048 BOARD_AVB_VENDOR_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP) BOARD_AVB_VENDOR_ROLLBACK_INDEX_LOCATION := 1
ด้วยการกำหนดค่านี้ bootloader คาดว่าจะพบส่วนท้ายของ vbmeta ที่ส่วนท้ายของ system
และพาร์ติชันของ vendor
เนื่องจาก bootloader ไม่สามารถมองเห็นพาร์ติชันเหล่านี้ได้อีกต่อไป (ซึ่งอยู่ใน super
) จึงจำเป็นต้องทำการเปลี่ยนแปลงสองอย่าง
- เพิ่มพาร์ติชัน
vbmeta_system
และvbmeta_vendor
ลงในตารางพาร์ติชันของอุปกรณ์ สำหรับอุปกรณ์ A/B ให้เพิ่มvbmeta_system_a
,vbmeta_system_b
,vbmeta_vendor_a
และvbmeta_vendor_b
หากเพิ่มพาร์ติชั่นเหล่านี้อย่างน้อยหนึ่งพาร์ติชั่น พาร์ติชั่นควรมีขนาดเท่ากับพาร์ติvbmeta
- เปลี่ยนชื่อแฟล็กการกำหนดค่าโดยเพิ่ม
VBMETA_
และระบุว่าพาร์ติชั่นใดที่ chaining ขยายไปถึง:BOARD_AVB_VBMETA_SYSTEM := system BOARD_AVB_VBMETA_SYSTEM_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem BOARD_AVB_VBMETA_SYSTEM_ALGORITHM := SHA256_RSA2048 BOARD_AVB_VBMETA_SYSTEM_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP) BOARD_AVB_VBMETA_SYSTEM_ROLLBACK_INDEX_LOCATION := 1 BOARD_AVB_VBMETA_VENDOR := vendor BOARD_AVB_VBMETA_VENDOR_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem BOARD_AVB_VBMETA_VENDOR_ALGORITHM := SHA256_RSA2048 BOARD_AVB_VBMETA_VENDOR_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP) BOARD_AVB_VBMETA_VENDOR_ROLLBACK_INDEX_LOCATION := 1
อุปกรณ์อาจใช้หนึ่งพาร์ติชัน ทั้งสอง หรือไม่มีพาร์ติชันเหล่านี้ การเปลี่ยนแปลงจำเป็นเฉพาะเมื่อโยงกับโลจิคัลพาร์ติชันเท่านั้น
AVB bootloader เปลี่ยนไป
หาก bootloader ได้ฝัง libavb ไว้ ให้รวมแพตช์ต่อไปนี้:
- 818cf56740775446285466eda984acedd4baeac0 — "libavb: เฉพาะ GUID ของพาร์ติชันการสืบค้นเท่านั้นเมื่อ cmdline ต้องการ"
- 5abd6bc2578968d24406d834471adfd995a0c2e9 — "อนุญาตให้ไม่มีพาร์ติชันระบบ"
- 9ba3b6613b4e5130fa01a11d984c6b5f0eb3af05 — "แก้ไข AvbSlotVerifyData->cmdline อาจเป็น NULL"
หากใช้พาร์ติชั่นแบบเชน ให้ใส่แพตช์เพิ่มเติม:
- 49936b4c0109411fdd38bd4ba3a32a01c40439a9 — "libavb: รองรับ vbmeta blobs ในตอนเริ่มต้นของพาร์ติชัน"
การเปลี่ยนแปลงบรรทัดคำสั่งเคอร์เนล
ต้องเพิ่มพารามิเตอร์ใหม่ androidboot.boot_devices
ในบรรทัดคำสั่งเคอร์เนล สิ่งนี้ถูกใช้โดย init
เพื่อเปิดใช้งาน /dev/block/by-name
symlink ควรเป็นองค์ประกอบพา ธ ของอุปกรณ์ไปยัง symlink ตามชื่อที่สร้างโดย ueventd
นั่นคือ /dev/block/platform/ device-path /by-name/ partition-name
อุปกรณ์ที่เปิดตัวด้วย Android 12 หรือใหม่กว่าต้องใช้ bootconfig เพื่อส่งผ่าน androidboot.boot_devices
ไปยัง init
ตัวอย่างเช่น หาก symlink ตามชื่อ super partition คือ /dev/block/platform/ soc/100000.ufshc /by-name/super
คุณสามารถเพิ่มพารามิเตอร์บรรทัดคำสั่งในไฟล์ BoardConfig.mk ได้ดังนี้:
BOARD_KERNEL_CMDLINE += androidboot.boot_devices=soc/100000.ufshcคุณสามารถเพิ่มพารามิเตอร์ bootconfig ในไฟล์ BoardConfig.mk ได้ดังนี้:
BOARD_BOOTCONFIG += androidboot.boot_devices=soc/100000.ufshc
การเปลี่ยนแปลง fstab
การซ้อนทับแผนผังอุปกรณ์และโครงสร้างอุปกรณ์ต้องไม่มีรายการ fstab ใช้ไฟล์ fstab ที่จะเป็นส่วนหนึ่งของ ramdisk
ต้องทำการเปลี่ยนแปลงไฟล์ fstab สำหรับโลจิคัลพาร์ติชัน:
- ฟิลด์แฟล็ก fs_mgr ต้องมีแฟล็กล
logical
และแฟล็กfirst_stage_mount
ที่เปิดตัวใน Android 10 ซึ่งระบุว่าพาร์ติชั่นจะติดตั้งในสเตจแรก - พาร์ติชั่นอาจระบุ
avb= vbmeta partition name
เป็นแฟfs_mgr
จากนั้นพาร์ติvbmeta
ที่ระบุจะถูกเตรียมข้อมูลเบื้องต้นโดยinit
สเตจแรกก่อนที่จะพยายามเมาต์อุปกรณ์ใดๆ - ฟิลด์
dev
ต้องเป็นชื่อพาร์ติชัน
รายการ fstab ต่อไปนี้ตั้งค่าระบบ ผู้ขาย และผลิตภัณฑ์เป็นโลจิคัลพาร์ติชันตามกฎข้างต้น
#<dev> <mnt_point> <type> <mnt_flags options> <fs_mgr_flags> system /system ext4 ro,barrier=1 wait,slotselect,avb=vbmeta,logical,first_stage_mount vendor /vendor ext4 ro,barrier=1 wait,slotselect,avb,logical,first_stage_mount product /product ext4 ro,barrier=1 wait,slotselect,avb,logical,first_stage_mount
คัดลอกไฟล์ fstab ไปยัง ramdisk ด่านแรก
การเปลี่ยนแปลงของ SELinux
อุปกรณ์ super partition block ต้องทำเครื่องหมายด้วย super_block_device
ตัวอย่างเช่น หาก symlink ตามชื่อ super partition คือ /dev/block/platform/ soc/100000.ufshc /by-name/super
ให้เพิ่มบรรทัดต่อไปนี้ใน file_contexts
:
/dev/block/platform/soc/10000\.ufshc/by-name/super u:object_r:super_block_device:s0
fastbootd
ตัวโหลดบูต (หรือเครื่องมือการกะพริบที่ไม่ใช่พื้นที่ผู้ใช้) ไม่เข้าใจพาร์ติชันแบบไดนามิก ดังนั้นจึงไม่สามารถแฟลชได้ เพื่อแก้ไขปัญหานี้ อุปกรณ์ต้องใช้พื้นที่ผู้ใช้ของโปรโตคอล fastboot ที่เรียกว่า fastbootd
สำหรับข้อมูลเพิ่มเติมเกี่ยวกับวิธีการใช้งาน fastbootd โปรดดูที่ การย้าย Fastboot ไปยัง User Space
adb remount
สำหรับนักพัฒนาที่ใช้ eng หรือ userdebug builds adb remount
มีประโยชน์อย่างมากสำหรับการวนซ้ำอย่างรวดเร็ว พาร์ติชันแบบไดนามิกก่อให้เกิดปัญหาในการเมาต์ adb remount
เนื่องจากไม่มีพื้นที่ว่างภายในระบบไฟล์แต่ละระบบอีกต่อไป เพื่อแก้ไขปัญหานี้ อุปกรณ์สามารถเปิดใช้งานโอเวอร์เลย์ได้ ตราบใดที่มีพื้นที่ว่างภายในซูเปอร์พาร์ติชั่น adb remount
จะสร้างพาร์ติชั่นไดนามิกชั่วคราวโดยอัตโนมัติและใช้โอเวอร์เลย์สำหรับการเขียน พาร์ติชั่นชั่วคราวมีชื่อว่า scratch
ดังนั้นอย่าใช้ชื่อนี้กับพาร์ติชั่นอื่น
สำหรับข้อมูลเพิ่มเติมเกี่ยวกับวิธีการเปิดใช้งานโอเวอร์เลย์ โปรดดู โอเวอร์เลย์ README ใน AOSP
กำลังอัปเกรดอุปกรณ์ Android
หากคุณอัปเกรดอุปกรณ์เป็น Android 10 และต้องการรวมการสนับสนุนพาร์ติชันแบบไดนามิกใน OTA คุณไม่จำเป็นต้องเปลี่ยนตารางพาร์ติชันในตัว จำเป็นต้องมีการกำหนดค่าพิเศษบางอย่าง
การเปลี่ยนแปลงการกำหนดค่าอุปกรณ์
หากต้องการติดตั้งเพิ่มเติมการแบ่งพาร์ติชันแบบไดนามิก ให้เพิ่มแฟล็กต่อไปนี้ใน device.mk
:
PRODUCT_USE_DYNAMIC_PARTITIONS := true PRODUCT_RETROFIT_DYNAMIC_PARTITIONS := true
การเปลี่ยนแปลงการกำหนดค่าบอร์ด
คุณต้องตั้งค่าตัวแปรบอร์ดต่อไปนี้:
- ตั้งค่า
BOARD_SUPER_PARTITION_BLOCK_DEVICES
เป็นรายการอุปกรณ์บล็อกที่ใช้เก็บขอบเขตของพาร์ติชันแบบไดนามิก นี่คือรายชื่อของฟิสิคัลพาร์ติชันที่มีอยู่ในอุปกรณ์ - ตั้งค่า
BOARD_SUPER_PARTITION_ partition _DEVICE_SIZE
เป็นขนาดของอุปกรณ์บล็อกแต่ละตัวในBOARD_SUPER_PARTITION_BLOCK_DEVICES
ตามลำดับ นี่คือรายการขนาดของฟิสิคัลพาร์ติชันที่มีอยู่ในอุปกรณ์ โดยปกติจะเป็นBOARD_ partition IMAGE_PARTITION_SIZE
ในการกำหนดค่าบอร์ดที่มีอยู่ - ยกเลิก
BOARD_ partition IMAGE_PARTITION_SIZE
ที่มีอยู่สำหรับพาร์ติชั่นทั้งหมดในBOARD_SUPER_PARTITION_BLOCK_DEVICES
- ตั้งค่า
BOARD_SUPER_PARTITION_SIZE
เป็นผลรวมของBOARD_SUPER_PARTITION_ partition _DEVICE_SIZE
- ตั้งค่า
BOARD_SUPER_PARTITION_METADATA_DEVICE
เป็นอุปกรณ์บล็อกที่เก็บข้อมูลเมตาของพาร์ติชันแบบไดนามิก ต้องเป็นหนึ่งในBOARD_SUPER_PARTITION_BLOCK_DEVICES
โดยปกติ ค่านี้จะถูกตั้งค่าเป็นsystem
- ตั้งค่า
BOARD_SUPER_PARTITION_GROUPS
,BOARD_ group _SIZE
และBOARD_ group _PARTITION_LIST
ตามลำดับ ดู การเปลี่ยนแปลงการกำหนดค่าบอร์ดในอุปกรณ์ใหม่ สำหรับรายละเอียด
ตัวอย่างเช่น หากอุปกรณ์มีระบบและพาร์ติชั่นผู้จำหน่ายอยู่แล้ว และคุณต้องการแปลงเป็นพาร์ติชั่นไดนามิกและเพิ่มพาร์ติชั่นผลิตภัณฑ์ใหม่ในระหว่างการอัพเดต ให้ตั้งค่าคอนฟิกบอร์ดนี้:
BOARD_SUPER_PARTITION_BLOCK_DEVICES := system vendor BOARD_SUPER_PARTITION_METADATA_DEVICE := system # Rename BOARD_SYSTEMIMAGE_PARTITION_SIZE to BOARD_SUPER_PARTITION_SYSTEM_DEVICE_SIZE. BOARD_SUPER_PARTITION_SYSTEM_DEVICE_SIZE := <size-in-bytes> # Rename BOARD_VENDORIMAGE_PARTITION_SIZE to BOARD_SUPER_PARTITION_VENDOR_DEVICE_SIZE BOARD_SUPER_PARTITION_VENDOR_DEVICE_SIZE := <size-in-bytes> # This is BOARD_SUPER_PARTITION_SYSTEM_DEVICE_SIZE + BOARD_SUPER_PARTITION_VENDOR_DEVICE_SIZE BOARD_SUPER_PARTITION_SIZE := <size-in-bytes> # Configuration for dynamic partitions. For example: BOARD_SUPER_PARTITION_GROUPS := group_foo BOARD_GROUP_FOO_SIZE := <size-in-bytes> BOARD_GROUP_FOO_PARTITION_LIST := system vendor product
การเปลี่ยนแปลงของ SELinux
อุปกรณ์ super partition block ต้องทำเครื่องหมายด้วยแอตทริบิวต์ super_block_device_type
ตัวอย่างเช่น หากอุปกรณ์มี system
และพาร์ติชั่น vendor
อยู่แล้ว คุณต้องการใช้พาร์ติชั่นเป็นอุปกรณ์บล็อกเพื่อเก็บขอบเขตของพาร์ติชั่นไดนามิก และ symlink ตามชื่อจะถูกทำเครื่องหมายเป็น system_block_device
:
/dev/block/platform/soc/10000\.ufshc/by-name/system u:object_r:system_block_device:s0 /dev/block/platform/soc/10000\.ufshc/by-name/vendor u:object_r:system_block_device:s0
จากนั้นเพิ่มบรรทัดต่อไปนี้ใน device.te
:
typeattribute system_block_device super_block_device_type;
สำหรับคอนฟิกูเรชันอื่นๆ โปรดดูที่ การใช้พาร์ติชั่นไดนามิกบนอุปกรณ์ใหม่
สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการอัปเดตชุดติดตั้งเพิ่มเติม โปรดดูที่ OTA สำหรับอุปกรณ์ A/B ที่ไม่มี Dynamic Partitions
ภาพโรงงาน
สำหรับอุปกรณ์ที่เปิดใช้ด้วยการสนับสนุนพาร์ติชั่นไดนามิก ให้หลีกเลี่ยงการใช้ fastboot ของ userspace เพื่อแฟลชอิมเมจจากโรงงาน เนื่องจากการบูทไปที่ userspace จะช้ากว่าวิธีการแฟลชแบบอื่นๆ
เพื่อแก้ไขปัญหานี้ make dist
สร้างอิมเมจ super.img
เพิ่มเติม ซึ่งสามารถแฟลชโดยตรงไปยังซูเปอร์พาร์ติชั่น โดยจะรวมกลุ่มเนื้อหาของโลจิคัลพาร์ติชันโดยอัตโนมัติ ซึ่งหมายความว่าประกอบด้วย system.img
, vendor.img
และอื่นๆ นอกเหนือจากข้อมูลเมตาของ super
พาร์ติชัน อิมเมจนี้สามารถแฟลชโดยตรงไปยัง super
พาร์ติชั่นโดยไม่ต้องใช้เครื่องมือเพิ่มเติมหรือใช้ fastbootd หลังจาก super.img
จะถูกวางไว้ใน ${ANDROID_PRODUCT_OUT}
สำหรับอุปกรณ์ A/B ที่เปิดใช้พาร์ติชันแบบไดนามิก super.img
จะมีรูปภาพในช่อง A หลังจากแฟลชซูเปอร์อิมเมจโดยตรงแล้ว ให้ทำเครื่องหมายสล็อต A ว่าบูตได้ก่อนที่จะรีบูตอุปกรณ์
สำหรับอุปกรณ์ติดตั้งเพิ่มเติม ให้สร้าง make dist
build ชุดของอิมเมจ super_*.img
ที่สามารถแฟลชได้โดยตรงไปยังฟิสิคัลพาร์ติชันที่เกี่ยวข้อง ตัวอย่างเช่น make dist
builds super_system.img
และ super_vendor.img
เมื่อ BOARD_SUPER_PARTITION_BLOCK_DEVICES
เป็นผู้จำหน่ายระบบ รูปภาพเหล่านี้อยู่ในโฟลเดอร์ OTA ใน target_files.zip
ตัวแมปอุปกรณ์ที่จัดเก็บ-การปรับอุปกรณ์
การแบ่งพาร์ติชันแบบไดนามิกรองรับอ็อบเจ็กต์ Device-mapper ที่ไม่ได้กำหนดไว้จำนวนหนึ่ง สิ่งเหล่านี้อาจไม่สร้างอินสแตนซ์ทั้งหมดตามที่คาดไว้ ดังนั้นคุณต้องติดตามการต่อเชื่อมทั้งหมด และอัปเดตคุณสมบัติของ Android ของพาร์ติชั่นที่เกี่ยวข้องทั้งหมดด้วยอุปกรณ์จัดเก็บข้อมูลพื้นฐาน
กลไกภายใน init
ติดตามการเมานต์และอัปเดตคุณสมบัติของ Android แบบอะซิงโครนัส ระยะเวลาที่ใช้ไม่รับประกันว่าจะอยู่ภายในระยะเวลาที่กำหนด ดังนั้นคุณต้องให้เวลาเพียงพอสำหรับทั้งหมด on property
จะตอบสนอง คุณสมบัติคือ dev.mnt.blk. <partition>
โดยที่ <partition>
คือ root
, system
, data
หรือ vendor
เป็นต้น แต่ละพร็อพเพอร์ตี้เชื่อมโยงกับชื่ออุปกรณ์จัดเก็บข้อมูลฐาน ดังที่แสดงในตัวอย่างเหล่านี้:
taimen:/ % getprop | grep dev.mnt.blk [dev.mnt.blk.data]: [sda] [dev.mnt.blk.firmware]: [sde] [dev.mnt.blk.metadata]: [sde] [dev.mnt.blk.persist]: [sda] [dev.mnt.blk.root]: [dm-0] [dev.mnt.blk.vendor]: [dm-1] blueline:/ $ getprop | grep dev.mnt.blk [dev.mnt.blk.data]: [dm-4] [dev.mnt.blk.metadata]: [sda] [dev.mnt.blk.mnt.scratch]: [sda] [dev.mnt.blk.mnt.vendor.persist]: [sdf] [dev.mnt.blk.product]: [dm-2] [dev.mnt.blk.root]: [dm-0] [dev.mnt.blk.system_ext]: [dm-3] [dev.mnt.blk.vendor]: [dm-1] [dev.mnt.blk.vendor.firmware_mnt]: [sda]
ภาษา init.rc
อนุญาตให้ขยายคุณสมบัติของ Android โดยเป็นส่วนหนึ่งของกฎ และแพลตฟอร์มสามารถปรับแต่งอุปกรณ์จัดเก็บข้อมูลได้ตามต้องการด้วยคำสั่งดังนี้:
write /sys/block/${dev.mnt.blk.root}/queue/read_ahead_kb 128 write /sys/block/${dev.mnt.blk.data}/queue/read_ahead_kb 128
เมื่อการประมวลผลคำสั่งเริ่มต้นในขั้นที่สอง init
epoll loop
จะทำงาน และค่าต่างๆ จะเริ่มอัปเดต อย่างไรก็ตาม เนื่องจากทริกเกอร์คุณสมบัติไม่ทำงานจนกว่าจะถึงช่วงปลาย init
ไม่สามารถใช้ได้ในขั้นตอนการบู๊ตเริ่มต้นเพื่อจัดการกับ root
ท system
หรือ vendor
คุณอาจคาดว่าค่าดีฟอลต์ของเคอร์เนล read_ahead_kb
จะเพียงพอจนกว่าสคริปต์ init.rc
จะสามารถแทนที่ได้ใน early-fs
(เมื่อ daemons และสิ่งอำนวยความสะดวกต่างๆ เริ่มทำงาน) ดังนั้น Google ขอแนะนำให้คุณใช้ on property
ควบคู่ไปกับคุณสมบัติที่ควบคุมโดย init.rc
เช่น sys.read_ahead_kb
เพื่อจัดการกับกำหนดเวลาการดำเนินการและเพื่อป้องกันสภาวะการแข่งขัน ดังในตัวอย่างเหล่านี้:
on property:dev.mnt.blk.root=* && property:sys.read_ahead_kb=* write /sys/block/${dev.mnt.blk.root}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048} on property:dev.mnt.blk.system=* && property:sys.read_ahead_kb=* write /sys/block/${dev.mnt.blk.system}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048} on property:dev.mnt.blk.vendor=* && property:sys.read_ahead_kb=* write /sys/block/${dev.mnt.blk.vendor}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048} on property:dev.mnt.blk.product=* && property:sys.read_ahead_kb=* write /sys/block/${dev.mnt.blk.system_ext}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048} on property:dev.mnt.blk.oem=* && property:sys.read_ahead_kb=* write /sys/block/${dev.mnt.blk.oem}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048} on property:dev.mnt.blk.data=* && property:sys.read_ahead_kb=* write /sys/block/${dev.mnt.blk.data}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048} on early-fs: setprop sys.read_ahead_kb ${ro.read_ahead_kb.boot:-2048} on property:sys.boot_completed=1 setprop sys.read_ahead_kb ${ro.read_ahead_kb.bootcomplete:-128}