หากต้องการใช้ 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
จะต้องมากกว่าหรือเท่ากับ sum(ขนาดของกลุ่มการอัปเดต) + overhead ซึ่งในทางกลับกันจะต้องมากกว่าหรือเท่ากับ sum(ขนาดของพาร์ติชัน) + overhead
สำหรับ 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 ในขณะที่ใช้วิธีการบีบอัดแบบ no-op จากนั้นคุณสามารถกำหนดค่าวิธีการบีบอัดเป็นหนึ่งในวิธีที่รองรับ 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)
การบีบอัดแฮคเกอร์
สำหรับอุปกรณ์ที่อัปเกรดเป็น 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
การรวม Userspace จะเปิดใช้งานตามค่าเริ่มต้นในอุปกรณ์ที่เปิดตัวด้วยเวอร์ชัน 13 ขึ้นไป
ระบบควบคุมการบูต HAL
การควบคุมการบูต HAL จัดเตรียมอินเทอร์เฟซสำหรับไคลเอนต์ OTA เพื่อควบคุมสล็อตการบูต A/B เสมือนจำเป็นต้องมีการอัปเกรดเวอร์ชันรองของการควบคุมการบูต HAL เนื่องจากจำเป็นต้องมี API เพิ่มเติมเพื่อให้แน่ใจว่าโปรแกรมโหลดบูตได้รับการป้องกันในระหว่างการกะพริบ/รีเซ็ตเป็นค่าจากโรงงาน โปรดดู 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: รองรับแพตช์เคอร์เนลไฟล์ที่ปักหมุดไว้ ด้วยเช่นกัน
A/B เสมือนอาศัยคุณสมบัติที่เพิ่มในเคอร์เนลเวอร์ชัน 4.3: บิตสถานะ โอเวอร์โฟลว์ ใน snapshot
และเป้าหมาย snapshot-merge
อุปกรณ์ทั้งหมดที่เปิดตัวด้วย 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
สำหรับอุปกรณ์ติดตั้งเพิ่ม จะมีพื้นที่ว่างเพียงพอในพาร์ติชั่นพิเศษเสมอ เพื่อไม่ให้ไฟล์ 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 * sum(size of update groups) + overhead ซึ่งจะมากกว่าหรือเท่ากับ 2 * sum(ขนาดของพาร์ติชั่น) + ค่าโสหุ้ย .
การเปลี่ยนแปลง Bootloader
ในระหว่างขั้นตอนการรวมการอัปเดต /data
จะเก็บอินสแตนซ์ทั้งหมดของระบบปฏิบัติการ Android เท่านั้น เมื่อการย้ายเริ่มต้นขึ้น พาร์ติชัน system
เนทิฟ vendor
และพาร์ติชัน product
จะไม่สมบูรณ์จนกว่าการคัดลอกจะเสร็จสิ้น หากอุปกรณ์ถูกรีเซ็ตเป็นค่าเริ่มต้นจากโรงงานในระหว่างกระบวนการนี้ ไม่ว่าจะโดยการกู้คืนหรือผ่านกล่องโต้ตอบการตั้งค่าระบบ อุปกรณ์จะไม่สามารถบูตได้
ก่อนที่จะลบ /data
ให้เสร็จสิ้นการผสานในการกู้คืนหรือย้อนกลับ ขึ้นอยู่กับสถานะของอุปกรณ์:
- หากบิลด์ใหม่บูตได้สำเร็จก่อนหน้านี้ ให้ทำการโยกย้ายให้เสร็จสิ้น
- มิฉะนั้น ให้ย้อนกลับไปยังช่องเก่า:
- สำหรับพาร์ติชันแบบไดนามิก ให้ย้อนกลับไปสู่สถานะก่อนหน้า
- สำหรับพาร์ติชันแบบสแตติก ให้ตั้งค่าสล็อตที่ใช้งานอยู่เป็นสล็อตเก่า
ทั้ง bootloader และ fastbootd
สามารถลบพาร์ติชัน /data
ได้หากอุปกรณ์ถูกปลดล็อค แม้ว่า fastbootd
สามารถบังคับให้การย้ายข้อมูลเสร็จสิ้นได้ แต่ bootloader ก็ไม่สามารถทำได้ bootloader ไม่ทราบว่ากำลังดำเนินการผสานอยู่หรือไม่ หรือบล็อกใดใน /data
ที่ประกอบเป็นพาร์ติชันระบบปฏิบัติการ อุปกรณ์จะต้องป้องกันไม่ให้ผู้ใช้ทำให้อุปกรณ์ใช้งานไม่ได้โดยไม่รู้ตัว (อิฐ) โดยทำดังต่อไปนี้:
- ใช้การควบคุมการบูต HAL เพื่อให้ bootloader สามารถอ่านค่าที่กำหนดโดยเมธอด
setSnapshotMergeStatus()
- หากสถานะการผสานคือ
MERGING
หรือหากสถานะการผสานคือSNAPSHOTTED
และช่องเปลี่ยนเป็นช่องที่อัปเดตใหม่ ดังนั้นคำขอให้ล้างuserdata
metadata
หรือพาร์ติชันที่จัดเก็บสถานะการผสานจะต้องถูกปฏิเสธในบูตโหลดเดอร์ - ใช้คำสั่ง
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
bootloader จะต้องส่งคืนsnapshotted
- มิฉะนั้น bootloader จะต้องส่งคืน
none
- หากสถานะเป็น
-
snapshot-update merge
— ดำเนินการผสานให้เสร็จสมบูรณ์ โดยบูตเป็นการกู้คืน/บูตอย่างรวดเร็วหากจำเป็น คำสั่งนี้ใช้ได้เฉพาะในกรณีที่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
วิธีการบีบอัด OTA
แพ็คเกจ Ota สามารถปรับแต่งตามตัวชี้วัดประสิทธิภาพที่แตกต่างกันได้ ปัจจุบัน Android มีวิธีการบีบอัดที่รองรับ ( gz
, lz4
และ none
) ซึ่งมีการแลกเปลี่ยนระหว่างเวลาติดตั้ง การใช้พื้นที่ COW เวลาบูต และเวลารวมสแนปช็อต ตัวเลือกเริ่มต้นที่เปิดใช้งานสำหรับ ab เสมือนพร้อมการบีบอัดคือ gz compression method
(หมายเหตุ: ประสิทธิภาพสัมพัทธ์ระหว่างวิธีการบีบอัดจะแตกต่างกันไปขึ้นอยู่กับความเร็วของ CPU และปริมาณงานการจัดเก็บข้อมูลซึ่งสามารถเปลี่ยนแปลงได้ขึ้นอยู่กับอุปกรณ์ แพ็คเกจ OTA ทั้งหมดที่สร้างขึ้นด้านล่างจะปิดใช้งาน PostInstall ซึ่งจะทำให้เวลาในการบูตช้าลงเล็กน้อย ขนาดพาร์ติชันไดนามิกรวม ของ ota เต็ม โดยไม่มีการบีบอัดคือ 4.81 GB )
OTA แบบเพิ่มหน่วยใน Pixel 6 Pro
เวลาติดตั้งโดยไม่มีขั้นตอนหลังการติดตั้ง | การใช้พื้นที่ของวัว | โพสต์เวลาบูต OTA | เวลารวมสแนปชอต | |
---|---|---|---|---|
กซ | 24 นาที | 1.18GB | 40.2 วินาที | 45.5 วินาที |
lz4 | 13 นาที | 1.49GB | 37.4 วินาที | 37.1 วินาที |
ไม่มี | 13 นาที | 2.90GB | 37.6 วินาที | 40.7 วินาที |
OTA เต็มรูปแบบบน Pixel 6 Pro
เวลาติดตั้งโดยไม่มีขั้นตอนหลังการติดตั้ง | การใช้พื้นที่ของ COW | โพสต์เวลาบูต OTA | เวลารวมสแนปชอต | |
---|---|---|---|---|
กซ | 23 นาที | 2.79GB | 24.9 วินาที | 41.7 วินาที |
lz4 | 12 นาที | 3.46GB | 20.0 วินาที | 25.3 วินาที |
ไม่มี | 10 นาที | 4.85GB | 20.6 วินาที | 29.8 วินาที |