ติดตั้งใช้งาน A/B เสมือนจริง

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

สร้างแฟล็ก

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

สำหรับอุปกรณ์ที่เปิดด้วย A/B เสมือน ให้ตั้งค่าให้อุปกรณ์นั้นรับค่า A/B เสมือน การกำหนดค่าฐานผู้ใช้:

$(call inherit-product, \
    $(SRC_TARGET_DIR)/product/virtual_ab_ota.mk)

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

สำหรับ Android 13 ขึ้นไป หากต้องการเปิดใช้ที่บีบอัด สแนปชอตที่มี A/B เสมือนเพื่อรับการกำหนดค่าพื้นฐานต่อไปนี้

$(call inherit-product, $(SRC_TARGET_DIR)/product/generic_ramdisk.mk)
$(call inherit-product, \
    $(SRC_TARGET_DIR)/product/virtual_ab_ota/android_t_baseline.mk)

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

PRODUCT_VIRTUAL_AB_COMPRESSION_METHOD := lz4

สำหรับ Android 12 หากต้องการเปิดใช้สแนปชอตที่บีบอัดด้วย A/B เสมือน รับการกำหนดค่าฐานต่อไปนี้

$(call inherit-product, $(SRC_TARGET_DIR)/product/generic_ramdisk.mk)
$(call inherit-product, \
    $(SRC_TARGET_DIR)/product/virtual_ab_ota/compression.mk)

การบีบอัด XOR

สำหรับอุปกรณ์ที่อัปเกรดเป็น Android 13 ขึ้นไป ฟีเจอร์การบีบอัด XOR ใช้ไม่ได้ เปิดใช้งานโดยค่าเริ่มต้น หากต้องการเปิดใช้การบีบอัด XOR ให้เพิ่มค่าต่อไปนี้ลงในไฟล์ .mk ไฟล์

PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.compression.xor.enabled=true

การบีบอัด XOR จะเปิดใช้โดยค่าเริ่มต้นสำหรับอุปกรณ์ที่รับช่วงมาจาก android_t_baseline.mk

การผสานพื้นที่ผู้ใช้

สำหรับอุปกรณ์ที่อัปเกรดเป็น Android 13 ขึ้นไป กระบวนการผสานรวมพื้นที่ผู้ใช้ตามที่อธิบายไว้ในโปรแกรมแมปอุปกรณ์ เลเยอร์ไม่ได้เปิดใช้โดย "ค่าเริ่มต้น" หากต้องการเปิดใช้การผสานพื้นที่ผู้ใช้ ให้เพิ่มบรรทัดต่อไปนี้ใน.mkของอุปกรณ์ ไฟล์:

PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.userspace.snapshots.enabled=true

การผสานพื้นที่ผู้ใช้จะเปิดใช้โดยค่าเริ่มต้นในอุปกรณ์ที่เปิดใช้ด้วย 13 ปีขึ้นไป

HAL การควบคุมการเปิดเครื่อง

ตัวควบคุมการเปิดเครื่อง ฮัลโหล มีอินเทอร์เฟซสำหรับไคลเอ็นต์ OTA เพื่อควบคุมช่องเปิดเครื่อง อัลฟา/เบต้าเสมือน ต้องมีการอัปเกรดเวอร์ชันย่อยของ HAL การควบคุมการเปิดเครื่อง เนื่องจาก API เพิ่มเติม ที่จำเป็นต่อการตรวจสอบว่า Bootloader ได้รับการป้องกันในระหว่างการกะพริบหรือรีเซ็ตเป็นค่าเริ่มต้น โปรดดู IBootControl.hal และ types.hal เพื่อดูนิยาม HAL เวอร์ชันล่าสุด

// hardware/interfaces/boot/1.1/types.hal
enum MergeStatus : uint8_t {
    NONE, UNKNOWN, SNAPSHOTTED, MERGING, CANCELLED };

// hardware/interfaces/boot/1.1/IBootControl.hal
package android.hardware.boot@1.1;
interface IBootControl extends @1.0::IBootControl {
    setSnapshotMergeStatus(MergeStatus status)
        generates (bool success);
    getSnapshotMergeStatus()
        generates (MergeStatus status);
}
// Recommended implementation

Return<bool> BootControl::setSnapshotMergeStatus(MergeStatus v) {
    // Write value to persistent storage
    // e.g. misc partition (using libbootloader_message)
    // bootloader rejects wipe when status is SNAPSHOTTED
    // or MERGING
}

การเปลี่ยนแปลง Fstab

ความสมบูรณ์ของพาร์ติชันข้อมูลเมตา สำคัญต่อกระบวนการเปิดเครื่อง โดยเฉพาะอย่างยิ่งหลังจากที่มีการใช้การอัปเดต OTA ดังนั้นพาร์ติชันข้อมูลเมตาต้อง ตรวจสอบก่อน first_stage_init ต่อเชื่อม เพื่อให้มั่นใจว่าจะเกิดขึ้น ให้เพิ่มแอตทริบิวต์ check fs_mgr ไปยังรายการสำหรับ /metadata รายการต่อไปนี้แสดง ตัวอย่าง:

/dev/block/by-name/metadata /metadata ext4 noatime,nosuid,nodev,discard,sync wait,formattable,first_stage_mount,check

ข้อกำหนดของเคอร์เนล

หากต้องการเปิดใช้การสร้างสแนปชอต ให้ตั้งค่า CONFIG_DM_SNAPSHOT เป็น true

สำหรับอุปกรณ์ที่ใช้ F2FS ให้ใส่ f2fs: ส่งออก FS_NOCOW_FL ไปที่ ผู้ใช้ของแพตช์เคอร์เนลเพื่อแก้ไขการปักหมุดไฟล์ รวม f2fs: ปักหมุดการสนับสนุนแล้ว ไฟล์เคอร์เนลด้วย

Virtual A/B พึ่งพาฟีเจอร์ที่เพิ่มเข้ามาในเคอร์เนลเวอร์ชัน 4.3 ได้แก่ overflow บิตสถานะในเป้าหมาย snapshot และ snapshot-merge กำลังเปิดใช้งานอุปกรณ์ทั้งหมด สำหรับ Android 9 ขึ้นไปควรมีเคอร์เนลเวอร์ชัน 4.4 ขึ้นไปอยู่แล้ว

หากต้องการเปิดใช้งานสแนปชอตที่บีบอัด เวอร์ชันเคอร์เนลขั้นต่ำที่รองรับคือ 4.19 ตั้งค่า CONFIG_DM_USER=m หรือ CONFIG_DM_USER=y หากใช้ตัวเลือกก่อนหน้า (โมดูล) โมดูลต้องโหลดใน RAM ดิสก์ขั้นตอนแรก ซึ่งสามารถทำได้โดย เพิ่มบรรทัดต่อไปนี้ลงใน Makefile ของอุปกรณ์

BOARD_GENERIC_RAMDISK_KERNEL_MODULES_LOAD := dm-user.ko

การปรับปรุงเพิ่มเติมในอุปกรณ์ที่อัปเกรดเป็น Android 11

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

  • ตำแหน่งของไฟล์ COW — สำหรับอุปกรณ์เปิดใช้งาน ไคลเอ็นต์ OTA จะใช้ พื้นที่ว่างทั้งหมดในซูเปอร์พาร์ติชันก่อนใช้พื้นที่ว่างใน /data สำหรับอุปกรณ์เพิ่มเติม จะมีพื้นที่เพียงพอใน เพื่อไม่สร้างไฟล์ COW ใน /data

  • แฟล็กฟีเจอร์ตามเวลาบิลด์ — สำหรับอุปกรณ์ที่เสริม A/B เสมือน ตั้งค่าทั้ง PRODUCT_VIRTUAL_AB_OTA และ PRODUCT_VIRTUAL_AB_OTA_RETROFIT แล้ว ถึง true ตามที่แสดงไว้ด้านล่างนี้

    (call inherit-product, \
      (SRC_TARGET_DIR)/product/virtual_ab_ota_retrofit.mk)
    
  • ขนาด Superพาร์ติชัน - อุปกรณ์ที่ใช้ A/B เสมือนสามารถตัด BOARD_SUPER_PARTITION_SIZE ในครึ่งเพราะสล็อต B ไม่ได้อยู่ใน Super พาร์ติชัน อุปกรณ์ที่ปรับ A/B เสมือนจะใช้การแบ่งพาร์ติชันขั้นสูงแบบเดิม ดังนั้น BOARD_SUPER_PARTITION_SIZE จึงมากกว่าหรือเท่ากับ 2 * ผลรวม(ขนาดของกลุ่มการอัปเดต) + โอเวอร์เฮด ซึ่งจะมากกว่าหรือเท่ากับ 2 * sum(ขนาดของพาร์ติชัน) + โอเวอร์เฮด

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

ในขั้นตอนการผสานของการอัปเดต /data จะเก็บอินสแตนซ์ทั้งหมด ระบบปฏิบัติการ Android เมื่อเริ่มการย้ายข้อมูลแล้ว system, vendor และ พาร์ติชัน product ยังไม่สมบูรณ์จนกว่าการคัดลอกจะเสร็จสิ้น หากอุปกรณ์คือ รีเซ็ตเป็นค่าเริ่มต้นจากโรงงานได้ในขั้นตอนนี้ ไม่ว่าจะโดยการกู้คืนหรือผ่านระบบ กล่องโต้ตอบการตั้งค่า อุปกรณ์จะเปิดเครื่องไม่ได้

ก่อนลบ /data ให้ผสานในการกู้คืนหรือย้อนกลับให้เสร็จสิ้นโดยขึ้นอยู่กับ สถานะของอุปกรณ์:

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

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

  1. ใช้ HAL การควบคุมการเปิดเครื่องเพื่อให้ Bootloader อ่านค่าที่ตั้งไว้ได้ โดยใช้เมธอด setSnapshotMergeStatus()
  2. หากสถานะการผสานเป็น MERGING หรือหากสถานะการผสานเป็น SNAPSHOTTED และช่องโฆษณาได้เปลี่ยนเป็นช่องที่อัปเดตใหม่ จากนั้นจะขอให้ล้างข้อมูล userdata, metadata หรือพาร์ติชันที่จัดเก็บสถานะการผสานต้องเป็น ถูกปฏิเสธใน Bootloader
  3. ใช้คำสั่ง fastboot snapshot-update cancel เพื่อให้ผู้ใช้ทำสิ่งต่อไปนี้ได้ ไปยัง Bootloader ว่าตนต้องการข้ามกลไกการป้องกันนี้
  4. แก้ไขเครื่องมือหรือสคริปต์แฟลชที่กำหนดเองเพื่อออก fastboot snapshot-update cancel เมื่อแฟลชอุปกรณ์ทั้งเครื่อง ข้อมูลนี้ปลอดภัยที่จะออกเนื่องจาก การแฟลชอุปกรณ์ทั้งเครื่องจะเป็นการนำ OTA ออก เครื่องมือสามารถตรวจจับคำสั่งนี้ได้ ขณะรันไทม์ด้วยการใช้ fastboot getvar snapshot-update-status ช่วงเวลานี้ ซึ่งจะช่วยแยกความแตกต่างระหว่างเงื่อนไขข้อผิดพลาดต่างๆ

ตัวอย่าง

struct VirtualAbState {
    uint8_t StructVersion;
    uint8_t MergeStatus;
    uint8_t SourceSlot;
};

bool ShouldPreventUserdataWipe() {
    VirtualAbState state;
    if (!ReadVirtualAbState(&state)) ...
    return state.MergeStatus == MergeStatus::MERGING ||
           (state.MergeStatus == MergeStatus::SNAPSHOTTED &&
            state.SourceSlot != CurrentSlot()));
}

การเปลี่ยนแปลงเกี่ยวกับเครื่องมือ Fastboot

Android 11 ทำการเปลี่ยนแปลงต่อไปนี้ใน Fastboot โปรโตคอล:

  • getvar snapshot-update-status — แสดงผลค่าที่การเปิดเครื่อง Control HAL ที่สื่อสารกับ Bootloader
    • หากสถานะคือ MERGING นั้น Bootloader จะต้องแสดงผล merging
    • หากสถานะคือ SNAPSHOTTED นั้น Bootloader จะต้องแสดงผล snapshotted
    • มิฉะนั้น Bootloader จะต้องแสดงผล none
  • snapshot-update merge — ดำเนินการผสานให้เสร็จสมบูรณ์ โดยจะเปิดเครื่องไปที่ การกู้คืน/fastbootd หากจำเป็น คำสั่งนี้จะใช้ได้ต่อเมื่อ snapshot-update-status คือ merging และรองรับใน Fastbootd เท่านั้น
  • snapshot-update cancel — ตั้งค่าสถานะการรวมของ HAL การควบคุมการเปิดเครื่องเป็น CANCELLED คำสั่งนี้ไม่ถูกต้องเมื่ออุปกรณ์ล็อกอยู่
  • erase หรือ wipeerase หรือ wipe ของ metadata, userdata หรือ พาร์ติชันที่คงสถานะการผสานสำหรับ HAL การควบคุมการเปิดเครื่องควรตรวจสอบ สถานะการผสานสแนปชอต หากสถานะเป็น MERGING หรือ SNAPSHOTTED ค่า อุปกรณ์ควรล้มเลิกการดำเนินการ
  • set_active — คำสั่ง set_active ที่เปลี่ยนช่องโฆษณาที่ใช้งานอยู่ ควรตรวจสอบสถานะการผสานสแนปชอต หากสถานะเป็น MERGING ค่า อุปกรณ์ควรล้มเลิกการดำเนินการ คุณสามารถเปลี่ยนช่องโฆษณาได้อย่างปลอดภัยใน รัฐSNAPSHOTTED

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

  1. การค้นหา getvar snapshot-update-status
  2. หากเป็น merging หรือ snapshotted จะเป็นฉบับ snapshot-update cancel
  3. ดำเนินการต่อด้วยการกะพริบ

ลดข้อกำหนดด้านพื้นที่เก็บข้อมูล

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

วิธีการบีบอัด OTA

คุณปรับแต่งแพ็กเกจ OTA เพื่อดูเมตริกประสิทธิภาพแบบต่างๆ ได้ Android มี วิธีบีบอัดที่รองรับหลายวิธี (gz, lz4, zstd และ none) ซึ่ง มีข้อดีข้อเสียระหว่างเวลาติดตั้ง การใช้พื้นที่ COW เวลาที่ใช้ในการเปิดเครื่อง และสแนปชอต ได้เวลารวม ตัวเลือกเริ่มต้นที่เปิดใช้งานสำหรับ ab เสมือนที่มีการบีบอัดคือ gz compression method (หมายเหตุ: ประสิทธิภาพที่สัมพันธ์กันระหว่างวิธีบีบอัด จะแตกต่างกันไปขึ้นอยู่กับความเร็วของ CPU และอัตราการส่งข้อมูลของพื้นที่เก็บข้อมูล ซึ่งอาจเปลี่ยนแปลงได้ บนอุปกรณ์ แพ็กเกจ OTA ทั้งหมดที่สร้างขึ้นด้านล่างมีการปิดใช้ PostInstall ซึ่ง จะทำให้เวลาเปิดเครื่องช้าลงเล็กน้อย ขนาดพาร์ติชันแบบไดนามิกทั้งหมดของ OTA ที่ไม่มีการบีบอัดจะเท่ากับ 4.81 GB)

OTA ที่เพิ่มขึ้นใน Pixel 6 Pro

เวลาติดตั้งที่ไม่มีระยะหลังการติดตั้ง การใช้งานพื้นที่ของ COW หลังเปิดเครื่อง OTA เวลาผสานสแนปชอต
GZ 24 นาที 1.18 GB 40.2 วินาที 45.5 วินาที
Lz4 13 นาที 1.49 GB 37.4 วินาที 37.1 วินาที
ไม่มี 13 นาที 2.90 GB 37.6 วินาที 40.7 วินาที

OTA เต็มรูปแบบใน Pixel 6 Pro

เวลาติดตั้งที่ไม่มีระยะหลังการติดตั้ง การใช้พื้นที่วัว หลังเปิดเครื่อง OTA เวลาผสานสแนปชอต
GZ 23 นาที 2.79 GB 24.9 วินาที 41.7 วินาที
Lz4 12 นาที 3.46 GB 20.0 วินาที 25.3 วินาที
ไม่มี 10 นาที 4.85 GB 20.6 วินาที 29.8 วินาที