การใช้งานไดนามิกพาร์ติชั่น

การแบ่งพาร์ติชันแบบไดนามิกดำเนินการโดยใช้โมดูล 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 แสดงตารางพาร์ติชั่นตัวอย่างก่อนและหลังการแปลงเป็นไดนามิกพาร์ติชั่น

เค้าโครงตารางพาร์ทิชัน
รูปที่ 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 ไว้ ให้รวมแพตช์ต่อไปนี้:

หากใช้พาร์ติชั่นแบบเชน ให้ใส่แพตช์เพิ่มเติม:

  • 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 ไม่สามารถใช้ได้ในขั้นตอนการบู๊ตเริ่มต้นเพื่อจัดการกับ rootsystem หรือ 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}