หากต้องการใช้ 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 ไม่ได้อยู่ในซูเปอร์อีกต่อไป นั่นคือ BOARD_SUPER_PARTITION_SIZE
ต้องมากกว่าหรือเท่ากับ ผลรวม (ขนาดของกลุ่มการอัปเดต) + ค่าโอเวอร์เฮด ซึ่งจะต้องมากกว่าหรือเท่ากับ ผลรวม (ขนาดของพาร์ติชัน) + ค่าโอเวอร์เฮด
สำหรับ Android 13 และสูงกว่า หากต้องการเปิดใช้สแน็ปช็อตที่บีบอัดด้วย Virtual 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)
สิ่งนี้เปิดใช้งานสแนปชอตพื้นที่ผู้ใช้ด้วย Virtual A/B ในขณะที่ใช้วิธีการบีบอัดแบบไม่มีการดำเนินการ จากนั้นคุณสามารถกำหนดค่าวิธีการบีบอัดเป็นหนึ่งในวิธีที่รองรับ gz
และ brotli
PRODUCT_VIRTUAL_AB_COMPRESSION_METHOD := gz
สำหรับ Android 12 หากต้องการเปิดใช้งานสแน็ปช็อตที่บีบอัดด้วย Virtual 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 ขึ้นไป กระบวนการผสานพื้นที่ผู้ใช้ตามที่อธิบายไว้ใน การแบ่งชั้น Device-mapper จะไม่ถูกเปิดใช้งานตามค่าเริ่มต้น หากต้องการเปิดใช้งานการผสานพื้นที่ผู้ใช้ ให้เพิ่มบรรทัดต่อไปนี้ในไฟล์ .mk
ของอุปกรณ์:
PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.userspace.snapshots.enabled=true
การรวม Userspace เปิดใช้งานโดยค่าเริ่มต้นบนอุปกรณ์ที่เปิดใช้งานตั้งแต่ 13 ขึ้นไป
การควบคุมการบูต HAL
การควบคุมการบูต HAL จัดเตรียมอินเทอร์เฟซสำหรับไคลเอนต์ OTA เพื่อควบคุมสล็อตบูต Virtual A/B ต้องการการอัปเกรดเวอร์ชันรองของการควบคุมการบูต 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: บิตสถานะ โอเวอร์โฟลว์ ใน snapshot
และเป้าหมาย snapshot-merge
อุปกรณ์ทั้งหมดที่เปิดตัวด้วย Android 9 และใหม่กว่าควรมีเคอร์เนลเวอร์ชัน 4.4 หรือใหม่กว่าอยู่แล้ว
หากต้องการเปิดใช้งานสแน็ปช็อตที่บีบอัด เวอร์ชันเคอร์เนลขั้นต่ำที่รองรับคือ 4.19 ตั้งค่า CONFIG_DM_USER=m
หรือ CONFIG_DM_USER=y
หากใช้โมดูลเดิม (โมดูล) จะต้องโหลดโมดูลในแรมดิสก์ขั้นแรก สามารถทำได้โดยเพิ่มบรรทัดต่อไปนี้ลงใน 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)
ขนาดซูเปอร์พาร์ติชัน — อุปกรณ์ที่เปิดใช้ A/B เสมือนสามารถลด
BOARD_SUPER_PARTITION_SIZE
ลงครึ่งหนึ่งได้ เนื่องจากสล็อต B ไม่ได้อยู่ในซูเปอร์พาร์ติชัน อุปกรณ์ที่ดัดแปลง A/B เสมือนจะเก็บขนาดพาร์ติชันเก่าไว้ ดังนั้นBOARD_SUPER_PARTITION_SIZE
จึงมากกว่าหรือเท่ากับ 2 * ผลรวม (ขนาดของกลุ่มการอัปเดต) + ค่าโอเวอร์เฮด ซึ่งจะมากกว่าหรือเท่ากับ 2 * ผลรวม (ขนาดของพาร์ติชัน) + ค่าโสหุ้ย .
การเปลี่ยนแปลง Bootloader
ระหว่างขั้นตอนการรวมการอัปเดต /data
จะเก็บอินสแตนซ์ทั้งหมดของระบบปฏิบัติการ Android เพียงตัวเดียว เมื่อการโอนย้ายเริ่มต้นขึ้น system
เนทีฟ vendor
และพาร์ติชัน product
จะไม่สมบูรณ์จนกว่าการคัดลอกจะเสร็จสิ้น หากอุปกรณ์ถูกรีเซ็ตเป็นค่าเริ่มต้นระหว่างขั้นตอนนี้ ไม่ว่าจะโดยการกู้คืนหรือผ่านกล่องโต้ตอบการตั้งค่าระบบ อุปกรณ์ก็จะไม่สามารถบู๊ตได้
ก่อนลบ /data
ให้เสร็จสิ้นการผสานในการกู้คืนหรือย้อนกลับ ทั้งนี้ขึ้นอยู่กับสถานะของอุปกรณ์:
- ถ้าบิวด์ใหม่บูทสำเร็จก่อน ให้ย้ายข้อมูลให้เสร็จ
- มิฉะนั้น ให้ย้อนกลับไปยังสล็อตเก่า:
- สำหรับพาร์ติชันไดนามิก ให้ย้อนกลับไปยังสถานะก่อนหน้า
- สำหรับพาร์ติชันแบบสแตติก ให้ตั้งค่าสล็อตที่ใช้งานเป็นสล็อตเก่า
ทั้ง bootloader และ fastbootd
สามารถลบพาร์ติชัน /data
ได้หากอุปกรณ์ไม่ได้ล็อก แม้ว่า fastbootd
สามารถบังคับให้การย้ายข้อมูลเสร็จสิ้น แต่ bootloader ทำไม่ได้ bootloader ไม่ทราบว่าการผสานกำลังดำเนินการอยู่หรือไม่ หรือบล็อกใดใน /data
ที่ประกอบเป็นพาร์ติชันระบบปฏิบัติการ อุปกรณ์ต้องป้องกันไม่ให้ผู้ใช้ทำให้อุปกรณ์ใช้งานไม่ได้โดยไม่รู้ตัว (bricking) โดยดำเนินการดังต่อไปนี้:
- ใช้การควบคุมการบูต HAL เพื่อให้ bootloader สามารถอ่านค่าที่กำหนดโดยเมธอด
setSnapshotMergeStatus()
- หากสถานะการผสานเป็น
MERGING
หรือถ้าสถานะการผสานเป็นSNAPSHOTTED
และสล็อตเปลี่ยนเป็นสล็อตที่อัปเดตใหม่ คำขอให้ล้างuserdata
metadata
หรือพาร์ติชันที่จัดเก็บสถานะการผสานจะต้องถูกปฏิเสธใน bootloader - ใช้คำสั่ง
fastboot snapshot-update cancel
เพื่อให้ผู้ใช้สามารถส่งสัญญาณไปยัง bootloader ว่าต้องการข้ามกลไกการป้องกันนี้ - ปรับเปลี่ยนเครื่องมือหรือสคริปต์การแฟลชแบบกำหนดเองเพื่อ
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
— ส่งคืนค่าที่ตัวควบคุมการบูต HAL สื่อสารกับ bootloader:- หากสถานะเป็น
MERGING
bootloader จะต้องส่งคืนmerging
- หากสถานะเป็น
SNAPSHOTTED
bootloader จะต้องส่งคืนsnapshotted
- มิฉะนั้น bootloader จะต้องส่งคืน
none
- หากสถานะเป็น
-
snapshot-update merge
— เสร็จสิ้นการดำเนินการผสาน บูทไปที่ Recovery/fastbootd ถ้าจำเป็น คำสั่งนี้ใช้ได้เฉพาะเมื่อmerging
snapshot-update-status
และรองรับใน fastbootd เท่านั้น -
snapshot-update cancel
— ตั้งค่าสถานะการผสานของการควบคุมการบูต HAL เป็นCANCELLED
คำสั่งนี้ใช้ไม่ได้เมื่ออุปกรณ์ถูกล็อก -
erase
หรือwipe
—erase
หรือwipe
metadata
userdata
หรือพาร์ติชันที่มีสถานะการผสานสำหรับการควบคุมการบูต HAL ควรตรวจสอบสถานะการรวมสแน็ปช็อต หากสถานะเป็นMERGING
หรือSNAPSHOTTED
อุปกรณ์ควรยกเลิกการทำงาน -
set_active
— คำสั่งset_active
ที่เปลี่ยนช่องที่ใช้งานอยู่ควรตรวจสอบสถานะการรวมสแนปชอต หากสถานะเป็นMERGING
อุปกรณ์ควรยกเลิกการทำงาน สล็อตสามารถเปลี่ยนได้อย่างปลอดภัยในสถานะSNAPSHOTTED
การเปลี่ยนแปลงเหล่านี้ออกแบบมาเพื่อป้องกันไม่ให้อุปกรณ์ไม่สามารถบู๊ตได้โดยไม่ตั้งใจ แต่อาจรบกวนการใช้เครื่องมืออัตโนมัติได้ เมื่อคำสั่งถูกใช้เป็นส่วนประกอบของการแฟลชพาร์ติชั่นทั้งหมด เช่น การรัน fastboot flashall
ขอแนะนำให้ใช้โฟลว์ต่อไปนี้:
- ค้นหา
getvar snapshot-update-status
- หาก
merging
หรือsnapshotted
snapshot-update cancel
- ดำเนินการตามขั้นตอนการกระพริบ
ลดความต้องการในการจัดเก็บ
อุปกรณ์ที่ไม่มีพื้นที่จัดเก็บ A/B เต็มรูปแบบที่จัดสรรไว้ใน super และคาดว่าจะใช้ /data
เท่าที่จำเป็น ขอแนะนำให้ใช้เครื่องมือการแมปบล็อก เครื่องมือการแมปบล็อกช่วยให้การจัดสรรบล็อกสอดคล้องกันระหว่างบิลด์ ลดการเขียนที่ไม่จำเป็นลงในสแน็ปช็อต สิ่งนี้ได้รับการบันทึกไว้ภายใต้ การลดขนาด OTA
วิธีการบีบอัด OTA
แพ็คเกจ Ota สามารถปรับได้สำหรับเมตริกประสิทธิภาพต่างๆ ขณะนี้ Android มีวิธีการบีบอัดที่รองรับอยู่สองสามวิธี ( gz
, lz4
และ none
) ซึ่งมีการแลกเปลี่ยนระหว่างเวลาติดตั้ง การใช้พื้นที่ COW เวลาบูต และเวลารวมสแน็ปช็อต ตัวเลือกเริ่มต้นที่เปิดใช้งานสำหรับ ab เสมือนที่มีการบีบอัดคือ gz compression method
(หมายเหตุ: ประสิทธิภาพสัมพัทธ์ระหว่างวิธีการบีบอัดจะแตกต่างกันไปขึ้นอยู่กับความเร็วของ CPU และปริมาณงานของพื้นที่จัดเก็บ ซึ่งสามารถเปลี่ยนแปลงได้ขึ้นอยู่กับอุปกรณ์ แพ็คเกจ OTA ทั้งหมดที่สร้างขึ้นด้านล่างจะปิดใช้งาน PostInstall ซึ่งจะทำให้เวลาบูตช้าลงเล็กน้อย ขนาดพาร์ติชันไดนามิกรวม ของ ota เต็ม ไม่มีการบีบอัดคือ 4.81 GB )
OTA ที่เพิ่มขึ้นใน Pixel 6 Pro
เวลาติดตั้งโดยไม่มีขั้นตอนหลังการติดตั้ง | การใช้พื้นที่ COW | โพสต์เวลาบูต OTA | เวลารวมสแนปชอต | |
---|---|---|---|---|
gz | 24 นาที | 1.18GB | 40.2 วินาที | 45.5 วินาที |
lz4 | 13 นาที | 1.49GB | 37.4 วินาที | 37.1 วินาที |
ไม่มี | 13 นาที | 2.90 กิกะไบต์ | 37.6 วินาที | 40.7 วินาที |
OTA เต็มรูปแบบใน Pixel 6 Pro
เวลาติดตั้งโดยไม่มีขั้นตอนหลังการติดตั้ง | การใช้พื้นที่ COW | โพสต์เวลาบูต OTA | เวลารวมสแนปชอต | |
---|---|---|---|---|
gz | 23 นาที | 2.79GB | 24.9 วินาที | 41.7 วินาที |
lz4 | 12 นาที | 3.46GB | 20.0 วินาที | 25.3 วินาที |
ไม่มี | 10 นาที | 4.85GB | 20.6 วินาที | 29.8 วินาที |