การแบ่งพาร์ติชันแบบไดนามิกถูกนำไปใช้โดยใช้โมดูล dm-linear device-mapper ในเคอร์เนล Linux ซุปเปอร์พาร์ติ super
ประกอบด้วยข้อมูลเมตาที่แสดงรายการชื่อและช่วงบล็อกของแต่ละพาร์ติชันไดนามิกภายใน super
ในระหว่างระยะแรก init
ข้อมูลเมตานี้จะถูกวิเคราะห์และตรวจสอบ และอุปกรณ์บล็อกเสมือนจะถูกสร้างขึ้นเพื่อแสดงถึงแต่ละพาร์ติชันไดนามิก
เมื่อใช้ OTA พาร์ติชันแบบไดนามิกจะถูกสร้างขึ้น ปรับขนาด หรือลบโดยอัตโนมัติตามความจำเป็น สำหรับอุปกรณ์ A/B จะมีสำเนาของข้อมูลเมตาสองชุด และการเปลี่ยนแปลงจะมีผลกับสำเนาที่แสดงถึงช่องเป้าหมายเท่านั้น
เนื่องจากมีการใช้พาร์ติชันแบบไดนามิกในพื้นที่ผู้ใช้ พาร์ติชันที่ bootloader ต้องการจึงไม่สามารถทำให้เป็นแบบไดนามิกได้ ตัวอย่างเช่น bootloader จะอ่าน boot
, dtbo
และ vbmeta
และจะต้องยังคงเป็นฟิสิคัลพาร์ติชัน
แต่ละพาร์ติชั่นไดนามิกสามารถอยู่ใน กลุ่มอัพเดตได้ กลุ่มเหล่านี้จะจำกัดพื้นที่สูงสุดที่พาร์ติชันในกลุ่มนั้นสามารถใช้ได้ ตัวอย่างเช่น 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 แสดงตารางพาร์ติชันตัวอย่างก่อนและหลังการแปลงเป็นพาร์ติชันแบบไดนามิก
พาร์ติชันไดนามิกที่รองรับคือ:
- ระบบ
- ผู้ขาย
- ผลิตภัณฑ์
- ต่อระบบ
- โอเอ็มเอ็ม
สำหรับอุปกรณ์ที่เปิดตัวด้วย 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
พาร์ติชันได้ในลักษณะที่คล้ายกัน:
# 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
- สำหรับอุปกรณ์เปิดใช้ Virtual A/B ขนาดรวมสูงสุดของทุกกลุ่มต้องไม่เกิน:
BOARD_SUPER_PARTITION_SIZE
- เหนือศีรษะ
ดู การนำ 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 ต้องไม่ใช้ระบบในฐานะรูท
อุปกรณ์ที่มีพาร์ติชันไดนามิก (ไม่ว่าจะเรียกใช้งานหรือติดตั้งพาร์ติชันไดนามิกเพิ่มเติม) ต้องไม่ใช้ระบบในฐานะรูท เคอร์เนล Linux ไม่สามารถตีความซุปเปอร์พาร์ super
ได้ ดังนั้นจึงไม่สามารถเมานต์ 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 หากอุปกรณ์ไม่ได้ใช้ chained partition descriptors ก็ไม่จำเป็นต้องเปลี่ยนแปลง อย่างไรก็ตาม หากใช้พาร์ติชันแบบลูกโซ่ และพาร์ติชันที่ตรวจสอบแล้วตัวใดตัวหนึ่งเป็นแบบไดนามิก จำเป็นต้องเปลี่ยนแปลง
ต่อไปนี้คือตัวอย่างการกำหนดค่าสำหรับอุปกรณ์ที่เชื่อมโยง 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_
และระบุพาร์ติชันที่การผูกมัดขยายไปยัง: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 ตามชื่อพาร์ติชันซุปเปอร์คือ /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 flags จะต้องมีแฟล็ก
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_block_device
ตัวอย่างเช่น หาก symlink ตามชื่อพาร์ติชั่นซุปเปอร์คือ /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
บูตเร็ว
bootloader (หรือเครื่องมือแฟลชที่ไม่ใช่พื้นที่ผู้ใช้) ไม่เข้าใจพาร์ติชันไดนามิก ดังนั้นจึงไม่สามารถแฟลชพาร์ติชั่นเหล่านั้นได้ เพื่อแก้ไขปัญหานี้ อุปกรณ์ต้องใช้การใช้พื้นที่ผู้ใช้ของโปรโตคอล fastboot ที่เรียกว่า fastbootd
สำหรับข้อมูลเพิ่มเติมเกี่ยวกับวิธีการใช้งาน fastbootd โปรดดูที่ การย้าย Fastboot ไปยัง User Space
adb ติดตั้งใหม่
สำหรับนักพัฒนาที่ใช้เวอร์ชัน eng หรือ userdebug การต่อ 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_block_device_type
ตัวอย่างเช่น หากอุปกรณ์มีพาร์ติชัน system
และ vendor
อยู่แล้ว คุณต้องการใช้พาร์ติชันเหล่านี้เป็นอุปกรณ์บล็อกเพื่อจัดเก็บขอบเขตของพาร์ติชันไดนามิก และลิงก์สัญลักษณ์ตามชื่อจะถูกทำเครื่องหมายเป็น 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 ที่ไม่มีพาร์ติชันแบบไดนามิก
ภาพโรงงาน
สำหรับอุปกรณ์ที่เรียกใช้งานด้วยการสนับสนุนพาร์ติชันแบบไดนามิก ให้หลีกเลี่ยงการใช้ 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
จะสร้างชุดของอิมเมจ super_*.img
ที่สามารถแฟลชไปยังฟิสิคัลพาร์ติชันที่เกี่ยวข้องได้โดยตรง ตัวอย่างเช่น make dist
builds super_system.img
และ super_vendor.img
เมื่อ BOARD_SUPER_PARTITION_BLOCK_DEVICES
เป็นผู้จำหน่ายระบบ รูปภาพเหล่านี้อยู่ในโฟลเดอร์ OTA ใน target_files.zip
การปรับอุปกรณ์จัดเก็บข้อมูลตัวทำแผนที่อุปกรณ์
การแบ่งพาร์ติชันแบบไดนามิกรองรับอ็อบเจ็กต์ตัวแมปอุปกรณ์ที่ไม่ได้กำหนดไว้จำนวนหนึ่ง สิ่งเหล่านี้อาจไม่เกิดขึ้นทั้งหมดตามที่คาดไว้ ดังนั้นคุณต้องติดตามการเมาท์ทั้งหมด และอัปเดตคุณสมบัติของ 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}