Sanal A/B'yi uygulayın

Yeni bir cihaza sanal A/B uygulamak veya başlatılan bir cihazı yenilemek için cihaza özel kodda değişiklikler yapmanız gerekir.

Bayraklar oluşturun

Sanal A/B kullanan cihazların A/B cihazı olarak yapılandırılması ve dinamik bölümlerle başlatılması gerekir.

Sanal A/B ile başlatılan cihazlar için, onları sanal A/B cihazı temel yapılandırmasını devralacak şekilde ayarlayın:

$(call inherit-product, \
    $(SRC_TARGET_DIR)/product/virtual_ab_ota.mk)

Sanal A/B ile başlatılan cihazların BOARD_SUPER_PARTITION_SIZE için yalnızca yarısı kadar kart boyutuna ihtiyacı vardır çünkü B yuvaları artık süper durumda değildir. Yani, BOARD_SUPER_PARTITION_SIZE toplamı (güncelleme gruplarının boyutu) + genel giderden büyük veya eşit olmalıdır; bu da toplam(bölümlerin boyutu) + giderden büyük veya ona eşit olmalıdır.

Android 13 ve üzeri için, Sanal A/B ile sıkıştırılmış anlık görüntüleri etkinleştirmek için aşağıdaki temel yapılandırmayı devralın:

$(call inherit-product, $(SRC_TARGET_DIR)/product/generic_ramdisk.mk)
$(call inherit-product, \
    $(SRC_TARGET_DIR)/product/virtual_ab_ota/android_t_baseline.mk)

Bu, işlem yapılmayan bir sıkıştırma yöntemi kullanılırken Sanal A/B ile kullanıcı alanı anlık görüntülerinin alınmasına olanak tanır. Daha sonra sıkıştırma yöntemini desteklenen yöntemlerden biri olan gz , zstd ve lz4 ile yapılandırabilirsiniz.

PRODUCT_VIRTUAL_AB_COMPRESSION_METHOD := lz4

Android 12 için Sanal A/B ile sıkıştırılmış anlık görüntüleri etkinleştirmek için aşağıdaki temel yapılandırmayı devralın:

$(call inherit-product, $(SRC_TARGET_DIR)/product/generic_ramdisk.mk)
$(call inherit-product, \
    $(SRC_TARGET_DIR)/product/virtual_ab_ota/compression.mk)

XOR sıkıştırması

Android 13 ve sonraki sürümlere yükseltme yapan cihazlarda XOR sıkıştırma özelliği varsayılan olarak etkin değildir. XOR sıkıştırmasını etkinleştirmek için aşağıdakini aygıtın .mk dosyasına ekleyin.

PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.compression.xor.enabled=true

XOR sıkıştırması, android_t_baseline.mk miras alan cihazlar için varsayılan olarak etkindir.

Kullanıcı alanı birleştirme

Android 13 ve sonraki sürümlere yükseltilen cihazlar için, Cihaz eşleyici katmanında açıklandığı gibi kullanıcı alanı birleştirme işlemi varsayılan olarak etkin değildir. Kullanıcı alanı birleştirmeyi etkinleştirmek için cihazın .mk dosyasına aşağıdaki satırı ekleyin:

PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.userspace.snapshots.enabled=true

Kullanıcı alanı birleştirme, 13 ve sonraki sürümlerle başlatılan cihazlarda varsayılan olarak etkindir.

Önyükleme kontrolü HAL

Önyükleme kontrolü HAL, OTA istemcilerinin önyükleme yuvalarını kontrol etmesi için bir arayüz sağlar. Sanal A/B, önyükleme kontrolü HAL'nin küçük bir sürüm yükseltmesini gerektirir çünkü önyükleyicinin yanıp sönme/fabrika ayarlarına sıfırlama sırasında korunmasını sağlamak için ek API'lere ihtiyaç vardır. HAL tanımının en son sürümü için IBootControl.hal ve type.hal'e bakın.

// 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 değişiklikleri

Meta veri bölümünün bütünlüğü, özellikle bir OTA güncellemesi uygulandıktan hemen sonra, önyükleme işlemi için çok önemlidir. Bu nedenle, meta veri bölümü, first_stage_init tarafından bağlanmadan önce kontrol edilmelidir. Bunun olmasını sağlamak için /metadata girişine check fs_mgr bayrağını ekleyin. Aşağıda bir örnek verilmektedir:

/dev/block/by-name/metadata /metadata ext4 noatime,nosuid,nodev,discard,sync wait,formattable,first_stage_mount,check

Çekirdek gereksinimleri

Anlık görüntüyü etkinleştirmek için CONFIG_DM_SNAPSHOT değerini true olarak ayarlayın.

F2FS kullanan cihazlar için f2fs'yi ekleyin: dosya sabitlemeyi düzeltmek için FS_NOCOW_FL bayrağını kullanıcı çekirdek düzeltme ekine aktarın . F2fs: desteği hizalanmış sabitlenmiş dosya çekirdek yamasını da ekleyin.

Sanal A/B, çekirdek sürüm 4.3'te eklenen özelliklere dayanır: snapshot taşma durumu biti ve snapshot-merge hedefleri. Android 9 ve üzeri sürümlerle başlatılan tüm cihazlarda, çekirdek sürümü 4.4 veya üzeri olmalıdır.

Sıkıştırılmış anlık görüntüleri etkinleştirmek için desteklenen minimum çekirdek sürümü 4.19'dur. CONFIG_DM_USER=m veya CONFIG_DM_USER=y ayarlayın. Eğer ilki (bir modül) kullanılıyorsa, modülün birinci aşamadaki ramdisk'e yüklenmesi gerekir. Bu, Makefile aygıtına aşağıdaki satırı ekleyerek başarılabilir:

BOARD_GENERIC_RAMDISK_KERNEL_MODULES_LOAD := dm-user.ko

Android 11'e yükseltilen cihazlarda güçlendirme

Android 11'e yükseltme yaparken, dinamik bölümlerle başlatılan cihazlar isteğe bağlı olarak sanal A/B'yi güçlendirebilir. Güncelleme süreci, bazı küçük farklılıklar dışında çoğunlukla sanal A/B ile başlatılan cihazlarla aynıdır:

  • COW dosyalarının konumu — Başlatma aygıtları için OTA istemcisi, /data içindeki alanı kullanmadan önce süper bölümdeki tüm kullanılabilir boş alanı kullanır. Yenileme cihazları için, süper bölümde her zaman yeterli alan vardır, böylece COW dosyası hiçbir zaman /data üzerinde oluşturulmaz.

  • Derleme zamanı özellik işaretleri — Sanal A/B'yi yenileyen cihazlar için, aşağıda gösterildiği gibi hem PRODUCT_VIRTUAL_AB_OTA hem de PRODUCT_VIRTUAL_AB_OTA_RETROFIT true olarak ayarlanmıştır:

    (call inherit-product, \
        (SRC_TARGET_DIR)/product/virtual_ab_ota_retrofit.mk)
    
  • Süper bölüm boyutu — Sanal A/B ile başlatılan cihazlar, B yuvaları süper bölümde olmadığından BOARD_SUPER_PARTITION_SIZE yarıya indirebilir. Sanal A/B'yi yenileyen cihazlar eski süper bölüm boyutunu korur; dolayısıyla BOARD_SUPER_PARTITION_SIZE , 2 * toplam(güncelleme gruplarının boyutu) + ek yüke eşit veya daha büyüktür; bu da 2 * toplam(bölümlerin boyutu)' ya eşit veya daha büyük olur + genel gider .

Önyükleyici değişiklikleri

Bir güncellemenin birleştirme adımı sırasında /data , Android işletim sisteminin tek tam örneğini tutar. Geçiş başladıktan sonra yerel system , vendor ve product bölümleri kopyalama bitene kadar tamamlanmamış olur. Bu işlem sırasında cihaz kurtarma yoluyla veya Sistem ayarları iletişim kutusu aracılığıyla fabrika ayarlarına sıfırlanırsa cihaz yeniden başlatılamaz.

/data öğesini silmeden önce, cihazın durumuna bağlı olarak kurtarma veya geri alma işleminde birleştirme işlemini tamamlayın:

  • Yeni yapı daha önce başarıyla başlatıldıysa taşıma işlemini tamamlayın.
  • Aksi takdirde eski yuvaya geri dönün:
    • Dinamik bölümler için önceki duruma geri dönün.
    • Statik bölümler için etkin yuvayı eski yuvaya ayarlayın.

Aygıtın kilidi açıksa hem önyükleyici hem de fastbootd /data bölümünü silebilir. fastbootd geçişi tamamlamaya zorlayabilir ancak önyükleyici bunu yapamaz. Önyükleyici, birleştirme işleminin devam edip etmediğini veya /data içindeki hangi blokların işletim sistemi bölümlerini oluşturduğunu bilmiyor. Cihazlar, aşağıdakileri yaparak kullanıcının bilmeden cihazı çalışmaz hale getirmesini (tuğlalama) önlemelidir:

  1. Önyükleyicinin setSnapshotMergeStatus() yöntemi tarafından ayarlanan değeri okuyabilmesi için önyükleme denetimi HAL'yi uygulayın.
  2. Birleştirme durumu MERGING ise veya birleştirme durumu SNAPSHOTTED ise ve yuva yeni güncellenen yuvaya değiştiyse, userdata , metadata veya birleştirme durumunu saklayan bölümü silme istekleri önyükleyicide reddedilmelidir.
  3. fastboot snapshot-update cancel komutunu uygulayın, böylece kullanıcılar önyükleyiciye bu koruma mekanizmasını atlamak istediklerini bildirebilirler.
  4. Tüm cihazın yanıp sönmesi sırasında fastboot snapshot-update cancel sağlamak için özel yanıp sönme araçlarını veya komut dosyalarını değiştirin. Cihazın tamamının yanıp sönmesi OTA'yı kaldırdığından bu sorun güvenlidir. Araçlar, fastboot getvar snapshot-update-status uygulayarak bu komutu çalışma zamanında algılayabilir. Bu komut hata durumlarını ayırt etmeye yardımcı olur.

Örnek

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 araç değişiklikleri

Android 11, fastboot protokolünde aşağıdaki değişiklikleri yapar:

  • getvar snapshot-update-status — HAL önyükleme denetiminin önyükleyiciye ilettiği değeri döndürür:
    • Durum MERGING ise, önyükleyicinin merging geri döndürmesi gerekir.
    • Durum SNAPSHOTTED ise, önyükleyicinin snapshotted döndürmesi gerekir.
    • Aksi takdirde, önyükleyicinin none döndürmesi gerekir.
  • snapshot-update merge — Gerekirse kurtarma/fastbootd'a önyükleme yaparak birleştirme işlemini tamamlar. Bu komut yalnızca snapshot-update-status merging geçerlidir ve yalnızca fastbootd'da desteklenir.
  • snapshot-update cancel — Önyükleme denetimi HAL'in birleştirme durumunu CANCELLED olarak ayarlar. Cihaz kilitliyken bu komut geçersizdir.
  • erase veya wipemetadata , userdata veya HAL önyükleme kontrolü için birleştirme durumunu tutan bir bölümün erase veya wipe anlık görüntü birleştirme durumunu kontrol etmelidir. Durum MERGING veya ANLIK SNAPSHOTTED ise cihazın işlemi iptal etmesi gerekir.
  • set_active — Etkin yuvayı değiştiren bir set_active komutu, anlık görüntü birleştirme durumunu kontrol etmelidir. Durum MERGING ise cihazın işlemi iptal etmesi gerekir. Yuva, SNAPSHOTTED durumunda güvenli bir şekilde değiştirilebilir.

Bu değişiklikler, bir cihazın kazara önyüklenemez hale gelmesini önlemek için tasarlanmıştır, ancak otomatikleştirilmiş araçlara zarar verebilirler. Komutlar fastboot flashall çalıştırmak gibi tüm bölümlerin yanıp sönmesinin bir bileşeni olarak kullanıldığında, aşağıdaki akışın kullanılması önerilir:

  1. getvar snapshot-update-status sorgulayın.
  2. merging veya snapshotted , snapshot-update cancel sorun.
  3. Yanıp sönen adımlarla devam edin.

Depolama gereksinimlerini azaltın

Süper olarak tahsis edilmiş tam A/B depolama alanına sahip olmayan ve gerektiğinde /data kullanmayı bekleyen cihazların, blok eşleme aracını kullanmaları önemle tavsiye edilir. Blok eşleme aracı, blok tahsisinin yapılar arasında tutarlı olmasını sağlayarak anlık görüntüye gereksiz yazma işlemlerini azaltır. Bu , OTA Boyutunun Azaltılması altında belgelenmiştir.

OTA sıkıştırma yöntemleri

OTA paketleri farklı performans ölçümlerine göre ayarlanabilir. Android, yükleme süresi, COW alanı kullanımı, önyükleme süresi ve anlık görüntü birleştirme süresi arasında ödünleşimler içeren, desteklenen çeşitli sıkıştırma yöntemleri ( gz , lz4 , zstd ve none ) sağlar. Sıkıştırmalı sanal ab için etkinleştirilen varsayılan seçenek gz compression method . (Not: Sıkıştırma yöntemleri arasındaki göreceli performans, CPU hızına ve depolama çıkışına bağlı olarak değişir ve cihaza bağlı olarak değişebilir. Aşağıda oluşturulan tüm OTA paketleri PostInstall devre dışıdır, bu da önyükleme süresini biraz yavaşlatır. Tam ota'nın toplam dinamik bölüm boyutu sıkıştırma olmadan 4,81 GB'dir ).

Pixel 6 Pro'da Artımlı OTA

Yükleme sonrası aşama olmadan yükleme süresi COW alanı kullanımı OTA önyükleme süresi sonrası Anlık görüntü birleştirme süresi
gz 24 dakika 1,18GB 40,2 saniye 45,5 saniye
lz4 13 dakika 1,49 GB 37,4 saniye 37,1 saniye
hiçbiri 13 dakika 2,90GB 37,6 saniye 40,7 saniye

Pixel 6 Pro'da Tam OTA

Yükleme sonrası aşama olmadan yükleme süresi İNEK Alan Kullanımı OTA önyükleme süresi sonrası Anlık görüntü birleştirme süresi
gz 23 dakika 2,79 GB 24,9 saniye 41,7 saniye
lz4 12 dakika 3,46GB 20,0 saniye 25,3 saniye
hiçbiri 10 dk 4,85 GB 20,6 saniye 29,8 saniye