หากต้องการใช้งาน 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(ขนาดของพาร์ติชั่น) + overhead
หากต้องการเปิดใช้งานสแน็ปช็อตที่บีบอัดด้วย Virtual A/B ให้รับค่าคอนฟิกูเรชันพื้นฐานต่อไปนี้แทน:
$(call inherit-product, \
$(SRC_TARGET_DIR)/product/virtual_ab_ota/compression.mk)
การควบคุมการบูต 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: รองรับไฟล์ แพทช์เคอร์เนลที่จัดตำแหน่งไว้ด้วยเช่นกัน
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 * ผลรวม (ขนาดของกลุ่มการอัพเดท) + โอเวอร์ เฮด ซึ่งจะมากกว่าหรือเท่ากับ 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
โปรแกรมโหลดบูตต้องส่งคืน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