새 기기에서 가상 A/B를 구현하거나 출시된 기기를 개조하려면 기기별 코드를 변경해야 합니다.
빌드 플래그
가상 A/B를 사용하는 장치 는 A/B 장치로 구성 해야 하며 동적 파티션으로 시작 해야 합니다.
가상 A/B로 시작하는 장치의 경우 가상 A/B 장치 기본 구성을 상속하도록 설정합니다.
$(call inherit-product, \
$(SRC_TARGET_DIR)/product/virtual_ab_ota.mk)
가상 A/B로 시작하는 기기는 B 슬롯이 더 이상 슈퍼에 없기 때문에 BOARD_SUPER_PARTITION_SIZE
에 대해 절반의 보드 크기만 필요합니다. 즉, BOARD_SUPER_PARTITION_SIZE
는 sum(업데이트 그룹의 크기) + 오버헤드 보다 크거나 같아야 하며, 이는 다시 sum(파티션 크기) + 오버헤드 보다 크거나 같아야 합니다.
Virtual A/B로 압축된 스냅샷을 활성화하려면 대신 다음 기본 구성을 상속하십시오.
$(call inherit-product, \
$(SRC_TARGET_DIR)/product/virtual_ab_ota/compression.mk)
부팅 제어 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 플래그를 사용자 커널 패치에 포함하여 파일 고정을 수정합니다. f2fs 포함: 정렬된 고정 파일 커널 패치도 지원 합니다.
가상 A/B는 커널 버전 4.3에 추가된 기능( snapshot
및 snapshot-merge
대상의 오버플 로 상태 비트)에 의존합니다. 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로 업그레이드하는 기기의 개조
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로 시작하는 기기는 B 슬롯이 슈퍼 파티션에 없기 때문에
BOARD_SUPER_PARTITION_SIZE
를 절반으로 줄일 수 있습니다. 가상 A/B를 개조하는 장치는 이전 슈퍼 파티션 크기를 유지하므로BOARD_SUPER_PARTITION_SIZE
는 2 * sum(업데이트 그룹 크기) + 오버헤드 보다 크거나 같으며, 이는 차례로 2 * sum(파티션 크기) 보다 크거나 같습니다. + 오버 헤드 .
부트로더 변경 사항
업데이트 병합 단계에서 /data
는 Android OS의 유일한 전체 인스턴스를 보유합니다. 마이그레이션이 시작되면 기본 system
, vendor
및 product
파티션은 복사가 완료될 때까지 불완전합니다. 복구 또는 시스템 설정 대화 상자를 통해 이 프로세스 동안 장치를 공장 초기화하면 장치를 부팅할 수 없습니다.
/data
를 지우기 전에 장치 상태에 따라 복구 또는 롤백에서 병합을 완료하십시오.
- 새 빌드가 이전에 성공적으로 부팅된 경우 마이그레이션을 완료합니다.
- 그렇지 않으면 이전 슬롯으로 롤백합니다.
- 동적 파티션의 경우 이전 상태로 롤백합니다.
- 정적 파티션의 경우 활성 슬롯을 이전 슬롯으로 설정합니다.
장치가 잠금 해제된 경우 부트로더와 fastbootd
모두 /data
파티션을 지울 수 있습니다. fastbootd
는 마이그레이션을 강제로 완료할 수 있지만 부트로더는 그렇게 할 수 없습니다. 부트로더는 병합이 진행 중인지 여부 또는 /data
의 어떤 블록이 OS 파티션을 구성하는지 알지 못합니다. 장치는 다음을 수행하여 사용자가 무의식적으로 장치를 작동 불능 상태로 만드는 것을 방지해야 합니다.
- 부트로더가
setSnapshotMergeStatus()
메소드에서 설정한 값을 읽을 수 있도록 부트 제어 HAL을 구현합니다. - 병합 상태가
MERGING
이거나 병합 상태가SNAPSHOTTED
이고 슬롯이 새로 업데이트된 슬롯으로 변경된 경우userdata
,metadata
또는 병합 상태를 저장하는 파티션 지우기 요청은 부트로더에서 거부되어야 합니다. - 사용자가 이 보호 메커니즘을 우회하고 싶다는 신호를 부트로더에 보낼 수 있도록
fastboot snapshot-update cancel
명령을 구현합니다. - 전체 장치를 플래싱할 때
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이 부트로더에 전달한 값을 반환합니다.- 상태가
MERGING
이면 부트로더는merging
을 반환해야 합니다. - 상태가
SNAPSHOTTED
이면 부트로더는snapshotted
을 반환해야 합니다. - 그렇지 않으면 부트로더가
none
을 반환해야 합니다.
- 상태가
-
snapshot-update merge
— 병합 작업을 완료하고 필요한 경우 복구/빠른 부팅으로 부팅합니다. 이 명령은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
를 실행합니다. - 깜박이는 단계를 진행합니다.
스토리지 요구 사항 감소
super에 전체 A/B 저장소가 할당되지 않고 필요에 따라 /data
를 사용할 것으로 예상되는 장치는 블록 매핑 도구를 사용하는 것이 좋습니다. 블록 매핑 도구는 빌드 간에 블록 할당을 일관되게 유지하여 스냅샷에 대한 불필요한 쓰기를 줄입니다. 이것은 OTA 크기 줄이기 에 설명되어 있습니다.