A/B güncellemelerini uygulayın

A/B sistem güncellemelerini uygulamak isteyen OEM'ler ve SoC satıcıları, önyükleyicilerinin boot_control HAL'yi uyguladığından ve doğru parametreleri çekirdeğe aktardığından emin olmalıdır.

Önyükleme denetimi HAL'yi uygulama

A/B özellikli önyükleyiciler, boot_control HAL'yi hardware/libhardware/include/hardware/boot_control.h adresinde uygulamalıdır. Uygulamaları system/extras/bootctl yardımcı programını ve system/extras/tests/bootloader/ kullanarak test edebilirsiniz.

Ayrıca aşağıda gösterilen durum makinesini de uygulamanız gerekir:

Şekil 1. Bootloader durum makinesi

Çekirdeği ayarlama

A/B sistemi güncellemelerini uygulamak için:

  1. Aşağıdaki çekirdek yaması serisini Cherrypick seçin (gerekirse):
  2. Çekirdek komut satırı bağımsız değişkenlerinin aşağıdaki ekstra bağımsız değişkenleri içerdiğinden emin olun:
    skip_initramfs rootwait ro init=/init root="/dev/dm-0 dm=system none ro,0 1 android-verity <public-key-id> <path-to-system-partition>"
    ... burada <public-key-id> değeri, doğruluk tablosu imzasını doğrulamak için kullanılan genel anahtarın kimliğidir (ayrıntılar için bkz . dm-verity ) .
  3. Genel anahtarı içeren .X509 sertifikasını sistem anahtarlığına ekleyin:
    1. .der formatında biçimlendirilmiş .X509 sertifikasını kernel dizininin köküne kopyalayın. .X509 sertifikası .pem dosyası olarak biçimlendirilmişse, .pem .der biçimine dönüştürmek için aşağıdaki openssl komutunu kullanın:
      openssl x509 -in <x509-pem-certificate> -outform der -out <x509-der-certificate>
    2. Sertifikayı sistem anahtarlığının bir parçası olarak eklemek için zImage oluşturun. Doğrulamak için procfs girişini kontrol edin ( KEYS_CONFIG_DEBUG_PROC_KEYS etkinleştirilmesini gerektirir):
      angler:/# cat /proc/keys
      
      1c8a217e I------     1 perm 1f010000     0     0 asymmetri
      Android: 7e4333f9bba00adfe0ede979e28ed1920492b40f: X509.RSA 0492b40f []
      2d454e3e I------     1 perm 1f030000     0     0 keyring
      .system_keyring: 1/4
      .X509 sertifikasının başarılı bir şekilde dahil edilmesi, sistem anahtarlığında genel anahtarın varlığını gösterir (vurgu genel anahtar kimliğini belirtir).
    3. Boşluğu # ile değiştirin ve çekirdek komut satırında <public-key-id> olarak iletin. Örneğin, <public-key-id> yerine Android:#7e4333f9bba00adfe0ede979e28ed1920492b40f iletin.

Derleme değişkenlerini ayarlama

A/B özellikli önyükleyiciler aşağıdaki derleme değişkeni kriterlerini karşılamalıdır:

A/B hedefi için tanımlanmalıdır
  • AB_OTA_UPDATER := true
  • AB_OTA_PARTITIONS := \
    boot \
    system \
    vendor
    ve update_engine aracılığıyla güncellenen diğer bölümler (radyo, önyükleyici vb.)
  • PRODUCT_PACKAGES += \
    update_engine \
    update_verifier
Örnek için /device/google/marlin/+/android-7.1.0_r1/device-common.mk adresine bakın. İsteğe bağlı olarak Derleme bölümünde açıklanan kurulum sonrası (ancak yeniden başlatma öncesi) dex2oat adımını gerçekleştirebilirsiniz.
A/B hedefi için kesinlikle önerilir
  • TARGET_NO_RECOVERY := true
  • BOARD_USES_RECOVERY_AS_BOOT := true
  • BOARD_RECOVERYIMAGE_PARTITION_SIZE tanımlamayın
A/B hedefi tanımlanamıyor
  • BOARD_CACHEIMAGE_PARTITION_SIZE
  • BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE
Hata ayıklama derlemeleri için isteğe bağlı PRODUCT_PACKAGES_DEBUG += update_engine_client

Bölümleri (yuvaları) ayarlayın

A/B cihazlarının bir kurtarma bölümüne veya önbellek bölümüne ihtiyacı yoktur çünkü Android artık bu bölümleri kullanmamaktadır. Veri bölümü artık indirilen OTA paketi için kullanılıyor ve kurtarma görüntüsü kodu önyükleme bölümünde bulunuyor. A/B-ed olan tüm bölümler şu şekilde adlandırılmalıdır (yuvalar her zaman a , b vb. olarak adlandırılır): boot_a , boot_b , system_a , system_b , vendor_a , vendor_b .

Önbellek

A/B olmayan güncellemeler için önbellek bölümü, indirilen OTA paketlerini depolamak ve güncellemeler uygulanırken blokları geçici olarak saklamak için kullanıldı. Önbellek bölümünü boyutlandırmanın hiçbir zaman iyi bir yolu olmadı: ne kadar büyük olması gerektiği, hangi güncellemeleri uygulamak istediğinize bağlıydı. En kötü durum, sistem görüntüsü kadar büyük bir önbellek bölümü olacaktır. A/B güncellemeleriyle blokları saklamanıza gerek yoktur (çünkü her zaman o anda kullanılmayan bir bölüme yazıyorsunuzdur) ve A/B akışıyla uygulamadan önce OTA paketinin tamamını indirmenize gerek yoktur.

İyileşmek

Kurtarma RAM diski artık boot.img dosyasında bulunmaktadır. Kurtarma işlemine geçerken, önyükleyici skip_initramfs seçeneğini çekirdek komut satırına koyamaz .

A/B olmayan güncellemeler için kurtarma bölümü, güncellemeleri uygulamak için kullanılan kodu içerir. A/B güncellemeleri, normal önyüklenen sistem görüntüsünde çalışan update_engine tarafından uygulanır. Fabrika verilerine sıfırlama ve güncelleme paketlerinin dışarıdan yüklenmesini uygulamak için kullanılan bir kurtarma modu hâlâ mevcuttur ("kurtarma" adı buradan gelmektedir). Kurtarma moduna ilişkin kod ve veriler, bir ramdisk'teki normal önyükleme bölümünde depolanır; sistem görüntüsüne önyükleme yapmak için, önyükleyici çekirdeğe ramdisk'i atlamasını söyler (aksi takdirde cihaz kurtarma moduna geçer. Kurtarma modu küçüktür (ve çoğu zaten önyükleme bölümündeydi), bu nedenle önyükleme bölümü artmaz boyutunda.

Fstab

A/B-ed bölümleri için slotselect argümanı satırda olmalıdır . Örneğin:

<path-to-block-device>/vendor  /vendor  ext4  ro
wait,verify=<path-to-block-device>/metadata,slotselect

Hiçbir bölüme vendor adı verilmemelidir. Bunun yerine, vendor_a veya vendor_b bölümü seçilecek ve /vendor bağlama noktasına bağlanacaktır.

Çekirdek yuvası bağımsız değişkenleri

Geçerli yuva son eki, belirli bir aygıt ağacı (DT) düğümü ( /firmware/android/slot_suffix ) veya androidboot.slot_suffix çekirdek komut satırı veya bootconfig bağımsız değişkeni aracılığıyla iletilmelidir.

Varsayılan olarak fastboot, bir A/B cihazındaki geçerli yuvayı yanıp söner. Güncelleme paketi aynı zamanda geçerli olmayan diğer yuvaya ait görüntüler de içeriyorsa, fastboot bu görüntüleri de yanıp söner. Mevcut seçenekler şunları içerir:

  • --slot SLOT . Varsayılan davranışı geçersiz kılın ve fastboot'tan bağımsız değişken olarak iletilen yuvayı flaş etmesini isteyin.
  • --set-active [ SLOT ] . Slotu aktif olarak ayarlayın. İsteğe bağlı bağımsız değişken belirtilmezse geçerli yuva etkin olarak ayarlanır.
  • fastboot --help . Komutlarla ilgili ayrıntıları öğrenin.

Önyükleyici fastboot'u uyguluyorsa, mevcut aktif yuvayı verilen yuvaya ayarlayan set_active <slot> komutunu desteklemelidir (bu aynı zamanda söz konusu yuva için önyüklenemez işaretini temizlemeli ve yeniden deneme sayısını varsayılan değerlere sıfırlamalıdır). Önyükleyici ayrıca aşağıdaki değişkenleri de desteklemelidir:

  • has-slot:<partition-base-name-without-suffix> . Verilen bölüm yuvaları destekliyorsa "evet"i, aksi takdirde "hayır"ı döndürür.
  • current-slot Bir sonraki başlatılacak yuva son ekini döndürür.
  • slot-count . Kullanılabilir yuvaların sayısını temsil eden bir tam sayı döndürür. Şu anda iki yuva desteklendiğinden bu değer 2 .
  • slot-successful:<slot-suffix> . Verilen yuva başarılı bir şekilde önyükleme olarak işaretlendiyse "evet", aksi takdirde "hayır" değerini döndürür.
  • slot-unbootable:<slot-suffix> . Verilen yuva önyüklenemez olarak işaretlenmişse "evet"i, aksi durumda "hayır"ı döndürür.
  • slot-retry-count . Belirtilen yuvayı başlatmayı denemek için kalan yeniden deneme sayısı.

Tüm değişkenleri görüntülemek için fastboot getvar all komutunu çalıştırın.

OTA paketleri oluşturun

OTA paketi araçları, A/B olmayan cihazlara yönelik komutlarla aynı komutları izler. target_files.zip dosyası, A/B hedefi için derleme değişkenleri tanımlanarak oluşturulmalıdır. OTA paket araçları, A/B güncelleyici formatındaki paketleri otomatik olarak tanımlar ve oluşturur.

Örnekler:

  • Tam bir OTA oluşturmak için:
    ./build/make/tools/releasetools/ota_from_target_files \
        dist_output/tardis-target_files.zip \
        ota_update.zip
    
  • Artımlı bir OTA oluşturmak için:
    ./build/make/tools/releasetools/ota_from_target_files \
        -i PREVIOUS-tardis-target_files.zip \
        dist_output/tardis-target_files.zip \
        incremental_ota_update.zip
    

Bölümleri yapılandırma

update_engine aynı diskte tanımlanan herhangi bir A/B bölümü çiftini güncelleyebilir. Bir çift bölümün ortak bir öneki ( system veya boot gibi) ve yuva başına son eki ( _a gibi) vardır. Yük oluşturucunun bir güncelleme tanımladığı bölümlerin listesi, AB_OTA_PARTITIONS make değişkeni tarafından yapılandırılır.

Örneğin, bir çift bootloader_a ve booloader_b bölümü dahil edilmişse ( _a ve _b yuva son ekleridir), ürün veya kart yapılandırmasında aşağıdakileri belirterek bu bölümleri güncelleyebilirsiniz:

AB_OTA_PARTITIONS := \
  boot \
  system \
  bootloader

update_engine tarafından güncellenen tüm bölümler sistemin geri kalanı tarafından değiştirilmemelidir. Artımlı veya delta güncellemeleri sırasında, mevcut yuvadaki ikili veriler, yeni yuvadaki verileri oluşturmak için kullanılır. Herhangi bir değişiklik, yeni slot verilerinin güncelleme işlemi sırasında doğrulamada başarısız olmasına ve dolayısıyla güncellemenin başarısız olmasına neden olabilir.

Kurulum sonrası yapılandırma

Bir dizi anahtar/değer çifti kullanarak, güncellenen her bölüm için kurulum sonrası adımını farklı şekilde yapılandırabilirsiniz. /system/usr/bin/postinst konumunda bulunan bir programı yeni bir görüntüde çalıştırmak için, sistem bölümündeki dosya sisteminin köküne göre yolu belirtin.

Örneğin, usr/bin/postinst system/usr/bin/postinst (RAM diski kullanılmıyorsa). Ek olarak, mount(2) sistem çağrısına aktarılacak dosya sistemi türünü belirtin. Ürün veya cihazın .mk dosyalarına (varsa) aşağıdakileri ekleyin:

AB_OTA_POSTINSTALL_CONFIG += \
  RUN_POSTINSTALL_system=true \
  POSTINSTALL_PATH_system=usr/bin/postinst \
  FILESYSTEM_TYPE_system=ext4

Uygulamaları derleyin

Uygulamalar, yeni sistem görüntüsüyle yeniden başlatmadan önce arka planda derlenebilir. Uygulamaları arka planda derlemek için ürünün cihaz yapılandırmasına (ürünün Device.mk dosyasında) aşağıdakileri ekleyin:

  1. Derleme komut dosyasının ve ikili dosyaların derlendiğinden ve sistem görüntüsüne dahil edildiğinden emin olmak için yerel bileşenleri yapıya ekleyin.
      # A/B OTA dexopt package
      PRODUCT_PACKAGES += otapreopt_script
    
  2. Derleme komut dosyasını, kurulum sonrası adım olarak çalışacak şekilde update_engine bağlayın.
      # A/B OTA dexopt update_engine hookup
      AB_OTA_POSTINSTALL_CONFIG += \
        RUN_POSTINSTALL_system=true \
        POSTINSTALL_PATH_system=system/bin/otapreopt_script \
        FILESYSTEM_TYPE_system=ext4 \
        POSTINSTALL_OPTIONAL_system=true
    

Kullanılmayan ikinci sistem bölümüne önceden seçilen dosyaların yüklenmesine ilişkin yardım için DEX_PREEPT dosyalarının ilk önyükleme kurulumuna bakın.