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

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

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

เนื่องจากมีการใช้พาร์ติชันแบบไดนามิกในพื้นที่ผู้ใช้ จึงจำเป็นต้องมีพาร์ติชัน โดย Bootloader จะเป็นแบบไดนามิกไม่ได้ เช่น boot Bootloader อ่าน dtbo และ vbmeta และ จึงต้องยังคงเป็นพาร์ติชันทางกายภาพ

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

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

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

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

การปรับแนวพาร์ติชัน

โมดูลเครื่องมือสร้างแผนที่อุปกรณ์อาจทำงานได้มีประสิทธิภาพน้อยลงหาก พาร์ติชัน super ไม่สอดคล้องกัน พาร์ติชัน super ต้องสอดคล้องกับ I/O ขั้นต่ำ ขนาดคำขอตามที่กำหนดโดยเลเยอร์บล็อก โดยค่าเริ่มต้น แอตทริบิวต์ ระบบบิลด์ (ผ่าน lpmake ซึ่งจะสร้างองค์ประกอบ อิมเมจพาร์ติชัน super) จะถือว่ามีการจัดแนว MiB 1 ก็เพียงพอต่อทุกพาร์ติชันแบบไดนามิกแล้ว อย่างไรก็ตาม ผู้ให้บริการควร ตรวจสอบว่าพาร์ติชัน 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 ขนาดสูงสุดของกลุ่มควรครอบคลุมเพียง 1 รายการ เนื่องจากชื่อกลุ่มจะเติมในช่องภายใน

ต่อไปนี้คือตัวอย่างอุปกรณ์ที่วางพาร์ติชันทั้งหมดลงในกลุ่ม ที่ชื่อ 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 ระยะแรกซึ่งอยู่ใน RAM

อย่าตั้งค่าBOARD_BUILD_SYSTEM_ROOT_IMAGE ใน Android 10 แฟล็ก BOARD_BUILD_SYSTEM_ROOT_IMAGE ใช้เพื่อ แยกความแตกต่างระหว่างระบบต่อเชื่อมโดยเคอร์เนลหรือโดย init ระยะแรกใน RAM

กำลังตั้งค่า 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 การเปิดเครื่องที่ได้รับการยืนยัน 2.0 หากอุปกรณ์ไม่ได้ใช้พาร์ติชันเชน ข้อบ่งชี้ ก็ไม่จำเป็นว่าจะต้องเปลี่ยนแปลงอะไร หากใช้เชน แต่พาร์ติชันที่ได้รับการยืนยัน 1 รายการเป็นแบบไดนามิก การเปลี่ยนแปลงจึงจำเป็น

ตัวอย่างการกำหนดค่าสำหรับอุปกรณ์ที่เชื่อมต่อ 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 ถ้า การเพิ่มพาร์ติชันเหล่านี้อย่างน้อย 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
    

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

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

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

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

  • 49936b4c0109411fdd38bd4ba3a32a01c40439a9 — "libavb: รองรับ vbmeta BLOB ในช่วงเริ่มต้นของพาร์ติชัน"

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

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

ตัวอย่างเช่น หากซูเปอร์พาร์ติชันตามชื่อลิงก์คือ /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 ที่จะเป็นส่วนหนึ่งของ RAM

ต้องทำการเปลี่ยนแปลงในไฟล์ 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 ไปยัง RAM ของขั้นตอนแรก

การเปลี่ยนแปลงใน 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 (หรือเครื่องมือ Flash ที่ไม่ใช่ userspace) ไม่เข้าใจ พาร์ติชันแบบไดนามิก ทำให้แฟลชไม่ได้ ในการแก้ปัญหานี้ อุปกรณ์ ต้องใช้พื้นที่ผู้ใช้ของโปรโตคอล Fastboot ซึ่งเรียกว่า Fastbootd

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

adb remount

สำหรับนักพัฒนาซอฟต์แวร์ที่ใช้บิลด์ EnDebug หรือ 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_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 ของพื้นที่ผู้ใช้เพื่อแฟลชอิมเมจเริ่มต้น เนื่องจากการเปิดไปยังพื้นที่ผู้ใช้คือ ช้ากว่าวิธีกะพริบอื่นๆ

เพื่อแก้ปัญหานี้ ตอนนี้ make dist จึงสร้าง รูปภาพ super.img ภาพที่สามารถแฟลชไปยัง พาร์ติชัน รวบรวมเนื้อหาของตรรกะ พาร์ติชัน ซึ่งหมายความว่ามี system.img vendor.img และอื่นๆ นอกเหนือจาก super ของพาร์ติชัน ภาพนี้สามารถแฟลชไปยัง พาร์ติชัน super โดยไม่ต้องมีเครื่องมือหรือการใช้งานเพิ่มเติม Fastbootd หลังจากบิลด์ super.img จะวางอยู่ใน ${ANDROID_PRODUCT_OUT}

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

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