หากต้องการใช้งาน 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
จะต้องมากกว่าหรือเท่ากับ sum(ขนาดของกลุ่มการอัพเดท) + overhead ซึ่งในทางกลับกันจะต้องมากกว่าหรือเท่ากับ sum(ขนาดของพาร์ติชั่น) + ค่าโสหุ้ย
สำหรับ 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 จะไม่เปิดใช้งานตามค่าเริ่มต้น หากต้องการเปิดใช้งานการรวม userspace ให้เพิ่มบรรทัดต่อไปนี้ในไฟล์ .mk
ของอุปกรณ์:
PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.userspace.snapshots.enabled=true
การผสาน Userspace เปิดใช้งานตามค่าเริ่มต้นในอุปกรณ์ที่เปิดตัวด้วย 13 ขึ้นไป
การควบคุมการบูต HAL
การ ควบคุมการบูต HAL จัดเตรียมอินเทอร์เฟซสำหรับไคลเอ็นต์ OTA เพื่อควบคุมช่องสำหรับบูต 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-merge
snapshot
ต อุปกรณ์ทั้งหมดที่เปิดตัวด้วย Android 9 และใหม่กว่าควรมีเคอร์เนลเวอร์ชัน 4.4 หรือใหม่กว่าอยู่แล้ว
ในการเปิดใช้งานสแน็ปช็อตที่บีบอัด เวอร์ชันเคอร์เนลขั้นต่ำที่รองรับคือ 4.19 ตั้งค่า CONFIG_DM_USER=m
หรือ CONFIG_DM_USER=y
หากใช้โมดูลเดิม (โมดูล) ต้องโหลดโมดูลใน ramdisk ระยะแรก สามารถทำได้โดยการเพิ่มบรรทัดต่อไปนี้ลงในอุปกรณ์ Makefile:
BOARD_GENERIC_RAMDISK_KERNEL_MODULES_LOAD := dm-user.ko
การติดตั้งเพิ่มเติมในอุปกรณ์ที่อัปเกรดเป็น Android 11
เมื่ออัปเกรดเป็น Android 11 อุปกรณ์ที่เปิดใช้พาร์ติชันแบบไดนามิกสามารถเลือกติดตั้ง A/B เสมือนเพิ่มเติมได้ กระบวนการอัปเดตส่วนใหญ่จะเหมือนกับอุปกรณ์ที่เปิดใช้ A/B เสมือน โดยมีข้อแตกต่างบางประการดังนี้
ตำแหน่งของไฟล์ COW — สำหรับอุปกรณ์ที่เรียกใช้งาน ไคลเอ็นต์ OTA จะใช้พื้นที่ว่างทั้งหมดที่มีอยู่ในซูเปอร์พาร์ติชั่นก่อนที่จะใช้พื้นที่ใน
/data
สำหรับอุปกรณ์สำหรับติดตั้งเพิ่มเติม จะมีที่ว่างเพียงพอใน super partition เสมอ เพื่อไม่ให้มีการสร้างไฟล์ 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
ประกอบเป็นพาร์ติชั่นระบบปฏิบัติการ อุปกรณ์ต้องป้องกันไม่ให้ผู้ใช้ทำให้อุปกรณ์ใช้งานไม่ได้ (อิฐ) โดยไม่รู้ตัว โดยทำดังนี้
- ใช้การควบคุมการบูต HAL เพื่อให้ bootloader สามารถอ่านค่าที่กำหนดโดย
setSnapshotMergeStatus()
- หากสถานะการรวมเป็น
MERGING
หรือหากสถานะการรวมเป็นSNAPSHOTTED
และสล็อตเปลี่ยนเป็นสล็อตที่อัพเดตใหม่ คำขอให้ลบข้อมูลผู้ใช้ ข้อมูลuserdata
metadata
หรือพาร์ติชั่นที่เก็บสถานะการผสานจะต้องถูกปฏิเสธใน bootloader - ใช้คำสั่ง
fastboot snapshot-update cancel
เพื่อให้ผู้ใช้สามารถส่งสัญญาณไปยัง bootloader ว่าต้องการข้ามกลไกการป้องกันนี้ - แก้ไขเครื่องมือหรือสคริปต์การกะพริบแบบกำหนดเองเพื่อ
fastboot snapshot-update cancel
เมื่อทำการแฟลชทั้งอุปกรณ์ ปัญหานี้มีความปลอดภัยเนื่องจากการแฟลชอุปกรณ์ทั้งหมดจะเป็นการนำ OTA ออก Tooling สามารถตรวจจับคำสั่งนี้ขณะรันไทม์โดยใช้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
โปรแกรมโหลดบูตต้องส่งคืนsnapshotted
- มิฉะนั้น bootloader จะต้องส่งคืน
none
- หากสถานะเป็น
-
snapshot-update merge
— ดำเนินการผสานให้เสร็จสิ้น บูตไปที่การกู้คืน/fastbootd หากจำเป็น คำสั่งนี้ใช้ได้เฉพาะในกรณีsnapshot-update-status
กำลังmerging
และได้รับการสนับสนุนใน 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 เต็มรูปแบบที่จัดสรรในระดับสูง และคาดว่าจะใช้ /data
ตามความจำเป็น ขอแนะนำอย่างยิ่งให้ใช้เครื่องมือการทำแผนที่แบบบล็อก เครื่องมือสร้างแผนที่บล็อกช่วยให้การจัดสรรบล็อกสอดคล้องกันระหว่างบิลด์ ช่วยลดการเขียนที่ไม่จำเป็นลงในสแน็ปช็อต เอกสารนี้อยู่ภายใต้ การลดขนาด OTA