새 기기에 가상 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/vabc_features.mk)
이렇게 하면 노옵스(no-ops) 압축 메서드를 사용하는 동안 가상 A/B로 사용자 공간 스냅샷을 사용할 수 있습니다. 그런 다음 지원되는 메서드인 zstd
와 lz4
중 하나로 압축 메서드를 구성할 수 있습니다. Android 15의 경우 기기 요구사항에 맞게 압축을 추가로 맞춤설정할 수 있습니다. 자세한 내용은 압축 미세 조정을 참고하세요.
PRODUCT_VIRTUAL_AB_COMPRESSION_METHOD := lz4
PRODUCT_VIRTUAL_AB_COMPRESSION_FACTOR := 65536
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
android_t_baseline.mk
에서 상속한 기기에서는 XOR 압축이 기본적으로 사용 설정됩니다.
사용자 공간 병합
최신 버전의 가상 A/B (Android T 이상)에서는 스냅샷 병합 프로세스가 완전히 사용자 공간에서 이루어집니다. 이 변경사항은 snapuserd 및 dm-user를 통해 가능합니다. Android 13 이상으로 출시되는 기기에는 기본적으로 사용자 공간 병합이 사용 설정되어 있으며, 이전 기기를 업그레이드하는 경우 다음을 사용하여 이 속성을 설정할 수 있습니다.
PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.userspace.snapshots.enabled=true
부팅 제어 HAL
부팅 제어 HAL은 OTA 클라이언트가 부팅 슬롯을 제어할 수 있는 인터페이스를 제공합니다. 가상 A/B에는 부팅 제어 HAL의 마이너 버전 업그레이드가 필요합니다. 플래시 또는 초기화 중에 부트로더를 보호하기 위해서는 추가 API가 필요하기 때문입니다. 최신 버전의 HAL 정의는 IBootControl.hal 및 types.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
가 마운트하기 전에 확인해야 합니다. 이렇게 하려면 /metadata
의 항목에 check
fs_mgr 플래그를 추가합니다. 다음은 예시입니다.
/dev/block/by-name/metadata /metadata ext4 noatime,nosuid,nodev,discard,sync wait,formattable,first_stage_mount,check
커널 요구사항
스냅샷 기능을 사용 설정하려면 CONFIG_DM_SNAPSHOT
을 true
로 설정합니다.
F2FS를 사용하는 기기의 경우 f2fs: export FS_NOCOW_FL flag to user 커널 패치를 포함하여 파일 고정 문제를 수정합니다. f2fs: support aligned pinned file 커널 패치도 포함하세요.
가상 A/B는 커널 버전 4.3에 추가된 기능(snapshot
및 snapshot-merge
타겟의 overflow 상태 비트)을 사용합니다. Android 9 이상으로 출시되는 모든 기기에는 이미 커널 버전 4.4 이상이 있습니다.
압축된 스냅샷을 사용 설정하는 데 필요한 최소 커널 버전은 4.19입니다.
CONFIG_DM_USER=m
또는 CONFIG_DM_USER=y
를 설정합니다. 전자(모듈)를 사용하는 경우, 모듈이 1단계 램디스크에 로드되어야 합니다. 이렇게 하려면 기기 Makefile에 다음 행을 추가하면 됩니다.
BOARD_GENERIC_RAMDISK_KERNEL_MODULES_LOAD := dm-user.ko
빠른 부팅 도구 변경사항
Android 11은 빠른 부팅 프로토콜을 다음과 같이 변경합니다.
getvar snapshot-update-status
- 부팅 제어 HAL이 부트로더에 전달한 값을 반환합니다.- 상태가
MERGING
이면 부트로더는merging
을 반환해야 합니다. - 상태가
SNAPSHOTTED
이면 부트로더는snapshotted
를 반환해야 합니다. - 그 외의 경우에는 부트로더가
none
을 반환해야 합니다.
- 상태가
snapshot-update merge
- 병합 작업을 완료하여 필요에 따라 복구/fastbootd로 부팅합니다. 이 명령어는snapshot-update-status
가merging
인 경우에만 유효하며 fastbootd에서만 지원됩니다.snapshot-update cancel
- 부팅 제어 HAL의 병합 상태를CANCELLED
로 설정합니다. 이 명령어는 기기가 잠겨 있으면 유효하지 않습니다.erase
또는wipe
-metadata
,userdata
또는 부팅 제어 HAL의 병합 상태를 보유하는 파티션의erase
또는wipe
는 스냅샷 병합 상태를 확인해야 합니다. 상태가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는 설치 시간과 COW 공간 사용, 부팅 시간, 스냅샷 병합 시간 간에 절충할 수 있는 여러 압축 메서드 (lz4
, zstd
, none
)를 지원합니다. 압축을 사용하는 가상 ab에 사용 설정된 기본 옵션은 lz4
compression method
입니다.
압축 미세 조정
압축 알고리즘은 두 가지 방법(압축 수준) (속도를 희생하여 달성한 압축량) 및 (압축 계수) (최대 압축 가능한 창 크기)를 통해 추가로 맞춤설정할 수 있습니다.
압축 수준은 zstd
와 같은 특정 알고리즘에서 사용할 수 있으며 수준을 변경하면 속도와 압축률 간에 절충점이 발생합니다.
압축 계수는 OTA 설치 중에 사용되는 최대 압축 창 크기를 나타냅니다. 기본값은 64k로 설정되지만 빌드 매개변수 PRODUCT_VIRTUAL_AB_COMPRESSION_FACTOR
를 맞춤설정하여 재정의할 수 있습니다. 지원되는 압축 계수는 4k, 8k, 16k, 32k, 64k, 128k, 256k입니다.
PRODUCT_VIRTUAL_AB_COMPRESSION_FACTOR := 65536
Pixel 8 Pro의 증분 OTA
PostInstall 단계가 없는 설치 시간 | COW 공간 사용 | OTA 후 부팅 시간 | 스냅샷 병합 시간 | |
---|---|---|---|---|
lz4 | 18분 15초 | 2.5 GB | 32.7초 | 98.6초 |
zstd | 24분 49초 | 2.05 GB | 36.3초 | 133.2초 |
없음 | 16분 42초 | 4.76 GB | 28.7초 | 76.6초 |
Pixel 8 Pro의 전체 OTA
PostInstall 단계가 없는 설치 시간 | COW 공간 사용 | OTA 후 부팅 시간 | 스냅샷 병합 시간 | |
---|---|---|---|---|
lz4 | 15분 11초 | 4.16 GB | 17.6초 | 82.2초 |
zstd | 16분 19초 | 3.46GB | 21.0초 | 106.3초 |
없음 | 13분 33초 | 6.39 GB | 18.5초 | 92.5초 |