ใช้พาร์ติชันแบบไดนามิก

การแบ่งพาร์ติชันแบบไดนามิกจะใช้โมดูล dm-linear device-mapper ในเคอร์เนล Linux พาร์ติชัน super มี ข้อมูลเมตาที่แสดงชื่อและช่วงบล็อกของแต่ละพาร์ติชันแบบไดนามิก ภายใน super ในระหว่างinitระยะแรก ระบบจะแยกวิเคราะห์และตรวจสอบข้อมูลเมตานี้ และสร้างอุปกรณ์บล็อกเสมือนเพื่อ แสดงถึงแต่ละพาร์ติชันแบบไดนามิก

เมื่อใช้ OTA ระบบจะสร้าง ปรับขนาด หรือลบพาร์ติชันแบบไดนามิกโดยอัตโนมัติตามความจำเป็น สำหรับอุปกรณ์ A/B จะมีข้อมูลเมตา 2 ชุด และการเปลี่ยนแปลงจะมีผลเฉพาะกับชุดที่แสดงถึง สล็อตเป้าหมาย

เนื่องจากมีการติดตั้งใช้งานพาร์ติชันแบบไดนามิกในพื้นที่ผู้ใช้ จึงไม่สามารถสร้างพาร์ติชันที่จำเป็น สำหรับโปรแกรมโหลดระบบให้เป็นแบบไดนามิกได้ เช่น 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 (GPT) พาร์ติชันเฉพาะผู้ให้บริการไม่จำเป็นต้องเป็นแบบไดนามิกและอาจอยู่ใน GPT

หากต้องการประมาณขนาดของ super ให้เพิ่มขนาดของ พาร์ติชันที่จะลบออกจาก GPT สำหรับอุปกรณ์ A/B ควรระบุขนาดของทั้ง 2 สล็อต รูปที่ 1 แสดง ตัวอย่างตารางพาร์ติชันก่อนและหลังการแปลงเป็นพาร์ติชันแบบไดนามิก

เลย์เอาต์ตารางพาร์ติชัน
รูปที่ 1 เลย์เอาต์ตารางการแบ่งพาร์ติชันจริงใหม่เมื่อ แปลงเป็นพาร์ติชันแบบไดนามิก

พาร์ติชันแบบไดนามิกที่รองรับมีดังนี้

  • ระบบ
  • ตัวแทนจำหน่ายรายย่อย
  • ผลิตภัณฑ์
  • System Ext
  • ODM

สำหรับอุปกรณ์ที่เปิดตัวด้วย Android 10 ตัวเลือกบรรทัดคำสั่งของเคอร์เนล androidboot.super_partition ต้องว่างเปล่าเพื่อให้ sysprop คำสั่ง ro.boot.super_partition ว่างเปล่า

การจัดแนวพาร์ติชัน

โมดูล Device-Mapper อาจทำงานได้ไม่เต็มประสิทธิภาพหาก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

การเปลี่ยนแปลงการกำหนดค่าอุปกรณ์

หากต้องการเปิดใช้การแบ่งพาร์ติชันแบบไดนามิก ให้เพิ่ม Flag ต่อไปนี้ใน 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 - ค่าใช้จ่าย
    ดูการติดตั้งใช้งานการทดสอบ 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

หากไม่ต้องการให้ระบบจัดสรรขนาดขั้นต่ำของการแบ่งพาร์ติชันโดยอัตโนมัติ คุณควบคุมขนาดพาร์ติชันได้ 2 วิธี คุณระบุ จำนวนพื้นที่ว่างขั้นต่ำได้ด้วย BOARD_partitionIMAGE_PARTITION_RESERVED_SIZE หรือจะระบุ BOARD_partitionIMAGE_PARTITION_SIZE เพื่อบังคับให้ พาร์ติชันแบบไดนามิกมีขนาดที่เฉพาะเจาะจงก็ได้ เราไม่แนะนำให้ใช้ทั้ง 2 วิธีนี้ เว้นแต่จำเป็น

เช่น

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 Kernel เพื่อตัดสินใจว่าจะบูตเข้าสู่โหมดใด สำหรับ อุปกรณ์ 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) จึงต้องมีการเปลี่ยนแปลง 2 อย่าง

  • เพิ่มพาร์ติชัน vbmeta_system และ vbmeta_vendor ลงในตารางพาร์ติชันของอุปกรณ์ สําหรับอุปกรณ์ A/B ให้เพิ่ม vbmeta_system_a, vbmeta_system_b vbmeta_vendor_a และ vbmeta_vendor_b หาก เพิ่มพาร์ติชันเหล่านี้อย่างน้อย 1 รายการ พาร์ติชันดังกล่าวควรมีขนาดเท่ากับ พาร์ติชัน 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

อุปกรณ์อาจใช้พาร์ติชันเหล่านี้อย่างใดอย่างหนึ่ง ทั้ง 2 อย่าง หรือไม่ใช้เลยก็ได้ การเปลี่ยนแปลง จำเป็นเมื่อเชื่อมโยงกับพาร์ติชันเชิงตรรกะเท่านั้น

การเปลี่ยนแปลง Bootloader ของ AVB

หาก Bootloader มี libavb แบบฝัง ให้รวมแพตช์ต่อไปนี้

หากใช้พาร์ติชันที่เชื่อมโยง ให้รวมแพตช์เพิ่มเติมดังนี้

  • 49936b4c0109411fdd38bd4ba3a32a01c40439a9 — "libavb: Support vbmeta blobs in beginning of partition."

การเปลี่ยนแปลงบรรทัดคำสั่งของเคอร์เนล

ต้องเพิ่มพารามิเตอร์ใหม่ androidboot.boot_devices ลงในบรรทัดคำสั่งของเคอร์เนล init ใช้ตัวแปรนี้เพื่อ เปิดใช้ลิงก์สัญลักษณ์ /dev/block/by-name โดยควรเป็น คอมโพเนนต์เส้นทางของอุปกรณ์ไปยัง Symlink ที่มีชื่อพื้นฐานซึ่งสร้างโดย ueventd นั่นคือ /dev/block/platform/device-path/by-name/partition-name อุปกรณ์ที่เปิดตัวด้วย Android 12 ขึ้นไปต้องใช้ bootconfig เพื่อส่ง androidboot.boot_devices ไปยัง init

ตัวอย่างเช่น หากซิมลิงก์แบบมีชื่อของพาร์ติชัน Super คือ /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

Device Tree และ Device Tree Overlay ต้องไม่มีรายการ fstab ใช้ไฟล์ fstab ที่จะเป็นส่วนหนึ่งของ ramdisk

ต้องทำการเปลี่ยนแปลงไฟล์ fstab สำหรับพาร์ติชันแบบตรรกะดังนี้

  • ฟิลด์แฟล็ก fs_mgr ต้องมีแฟล็ก logical และแฟล็ก first_stage_mount ซึ่งเปิดตัวใน Android 10 ซึ่งระบุว่าพาร์ติชันจะ ต้องติดตั้งในระยะแรก
  • พาร์ติชันอาจระบุ avb=vbmeta partition name เป็นแฟล็ก fs_mgr จากนั้นพาร์ติชัน vbmeta ที่ระบุ จะได้รับการเริ่มต้นโดย init ในระยะแรกก่อน พยายามติดตั้งอุปกรณ์ใดๆ
  • ฟิลด์ dev ต้องเป็นชื่อพาร์ติชัน

รายการ fstab ต่อไปนี้จะตั้งค่า system, vendor และ product เป็นพาร์ติชันเชิงตรรกะ ตามกฎข้างต้น

#<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 ตัวอย่างเช่น หากซิมลิงก์การแบ่งพาร์ติชันขั้นสูงตามชื่อคือ /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

Bootloader (หรือเครื่องมือแฟลชที่ไม่ใช่พื้นที่ผู้ใช้) ไม่เข้าใจ พาร์ติชันแบบไดนามิก จึงแฟลชพาร์ติชันเหล่านั้นไม่ได้ เพื่อแก้ไขปัญหานี้ อุปกรณ์ ต้องใช้การติดตั้งใช้งานโปรโตคอล fastboot ในพื้นที่ผู้ใช้ ซึ่งเรียกว่า fastbootd

ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีใช้งาน fastbootd ได้ที่ย้าย Fastboot ไปยังพื้นที่ผู้ใช้

adb remount

สำหรับนักพัฒนาแอปที่ใช้บิลด์ eng หรือ userdebug adb remount มีประโยชน์อย่างยิ่งสำหรับการทำซ้ำอย่างรวดเร็ว พาร์ติชันแบบไดนามิกทำให้เกิดปัญหาสำหรับ adb remount เนื่องจากไม่มีพื้นที่ว่าง ภายในระบบไฟล์แต่ละระบบอีกต่อไป อุปกรณ์สามารถเปิดใช้ overlayfs เพื่อแก้ไขปัญหานี้ได้ ตราบใดที่ยังมีพื้นที่ว่างภายในพาร์ติชันหลัก adb remount จะสร้างพาร์ติชันแบบไดนามิกชั่วคราวโดยอัตโนมัติ และใช้ overlayfs สำหรับการเขียน พาร์ติชันชั่วคราวมีชื่อว่า scratch ดังนั้นอย่าใช้ชื่อนี้กับพาร์ติชันอื่นๆ

ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีเปิดใช้ overlayfs ได้ที่ overlayfs 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_partitionIMAGE_PARTITION_SIZE จะอยู่ในบอร์ดที่มีอยู่ การกำหนดค่า
  • ยกเลิกการตั้งค่า BOARD_partitionIMAGE_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รูปภาพเพิ่มเติมที่แฟลชไปยังพาร์ติชัน super ได้โดยตรง โดยจะจัดกลุ่มเนื้อหาของพาร์ติชันเชิงตรรกะโดยอัตโนมัติ ซึ่งหมายความว่าจะมี system.img, vendor.img และอื่นๆ นอกเหนือจากข้อมูลเมตาของพาร์ติชัน super คุณแฟลชรูปภาพนี้ไปยังพาร์ติชัน super ได้โดยตรงโดยไม่ต้องใช้เครื่องมือเพิ่มเติมหรือใช้ fastbootd หลังจากสร้างแล้ว ระบบจะวาง super.img ไว้ใน ${ANDROID_PRODUCT_OUT}

สำหรับอุปกรณ์ A/B ที่เปิดตัวพร้อมพาร์ติชันแบบไดนามิก super.img มีอิมเมจในช่อง A หลังจากแฟลช อิมเมจ super โดยตรงแล้ว ให้ทำเครื่องหมายช่อง A เป็นช่องที่บูตได้ก่อนรีบูต อุปกรณ์

สำหรับอุปกรณ์ที่ดัดแปลง make dist จะสร้างชุด super_*.img อิมเมจที่แฟลชไปยัง พาร์ติชันจริงที่เกี่ยวข้องได้โดยตรง ตัวอย่างเช่น make dist สร้าง super_system.img และ super_vendor.img เมื่อ BOARD_SUPER_PARTITION_BLOCK_DEVICES เป็นผู้จำหน่าย ระบบ ระบบจะวางรูปภาพเหล่านี้ไว้ในโฟลเดอร์ OTA ใน target_files.zip

การปรับแต่งอุปกรณ์จัดเก็บข้อมูล Device Mapper

การแบ่งพาร์ติชันแบบไดนามิกรองรับออบเจ็กต์ 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ระยะที่ 2 epoll loop จะใช้งานได้ และค่าจะเริ่มอัปเดต อย่างไรก็ตาม เนื่องจากทริกเกอร์ของพร็อพเพอร์ตี้จะยังไม่ทำงานจนกว่าจะถึงช่วงปลายinit จึงไม่สามารถใช้ในขั้นตอนการบูตเริ่มต้นเพื่อจัดการ root, system หรือ vendor ได้ คุณอาจคาดหวังว่าread_ahead_kbเริ่มต้นของเคอร์เนลจะเพียงพอจนกว่าสคริปต์ init.rc จะลบล้างได้ใน early-fs (เมื่อเริ่มใช้ Daemon และสิ่งอำนวยความสะดวกต่างๆ) ดังนั้น 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}