A/B güncellemelerini uygulama

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

Önyükleme denetimi HAL'ı uygulama

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

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

Şekil 1. Bootloader durum makinesi

çekirdeğin ayarlanması

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

  1. Aşağıdaki çekirdek yama serisini 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 biçiminde biçimlendirilmiş .X509 sertifikasını kernel dizininin kök dizinine kopyalayın. .X509 sertifikası bir .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 dahil etmek 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ıyla dahil edilmesi, sistem anahtarlığında ortak anahtarın bulunduğunu gösterir (vurgu, genel anahtar kimliğini gösterir).
    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.

Yapı değişkenlerini ayarlama

A/B özellikli önyükleyiciler, aşağıdaki yapı değişkeni ölçütlerini 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
Bir örnek için /device/google/marlin/+/android-7.1.0_r1/device-common.mk adresine bakın. Derleme bölümünde açıklanan yükleme sonrası (ancak yeniden başlatma öncesi) dex2oat adımını isteğe bağlı olarak uygulayabilirsiniz.
A/B hedefi için şiddetle tavsiye edilir
  • TARGET_NO_RECOVERY := true
  • BOARD_USES_RECOVERY_AS_BOOT := true
  • BOARD_RECOVERYIMAGE_PARTITION_SIZE tanımlamayın
A/B hedefi için tanımlanamıyor
  • BOARD_CACHEIMAGE_PARTITION_SIZE
  • BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE
Hata ayıklama yapıları için isteğe bağlı PRODUCT_PACKAGES_DEBUG += update_engine_client

Bölümleri ayarlama (yuvalar)

Android artık bu bölümleri kullanmadığından A/B cihazlarının bir kurtarma bölümüne veya önbellek bölümüne ihtiyacı yoktur. Veri bölümü artık indirilen OTA paketi için kullanılır ve kurtarma görüntüsü kodu önyükleme bölümündedir. 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üncellemeleri uygularken 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üncellemeleri ile blokları saklamaya gerek yoktur (çünkü her zaman şu anda kullanılmayan bir bölüme yazıyorsunuzdur) ve akış A/B ile uygulamadan önce tüm OTA paketini indirmenize gerek yoktur.

İyileşmek

Kurtarma RAM diski artık boot.img dosyasında bulunmaktadır. Kurtarma işlemine girerken, önyükleyici çekirdek komut satırına skip_initramfs seçeneğini 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. Hala fabrika verilerine sıfırlama ve güncelleme paketlerinin yandan yüklenmesi ("kurtarma" adının geldiği yer) uygulamak için kullanılan bir kurtarma modu vardır. Kurtarma modu için kod ve veriler, bir ramdisk içindeki normal önyükleme bölümünde depolanır; önyükleyici, sistem görüntüsüne önyükleme yapmak için çekirdeğe ramdiski atlamasını söyler (aksi takdirde aygıt kurtarma moduna geçer. Kurtarma modu küçüktür (ve çoğu zaten önyükleme bölümündeydi), dolayısıyla önyükleme bölümünün boyutu artmaz.

Fstab

slotselect bağımsız değişkeni, A/B-ed bölümleri için 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üm vendor olarak adlandırılmamalıdır. 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 soneki, belirli bir aygıt ağacı (DT) düğümü ( /firmware/android/slot_suffix ) veya androidboot.slot_suffix çekirdek komut satırı veya bootconfig argümanı aracılığıyla iletilmelidir.

Varsayılan olarak, fastboot, bir A/B aygıtındaki geçerli yuvayı yanıp söner. Güncelleme paketi ayrıca diğer geçerli olmayan yuva için görüntüler 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ı flash etmesini isteyin.
  • --set-active [ SLOT ] . Yuvayı etkin 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 uygularsa, geçerli etkin yuvayı verilen yuvaya ayarlayan set_active <slot> komutunu desteklemelidir (bu aynı zamanda o yuva için önyüklenemez bayrağını 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", aksi takdirde "hayır" döndürür.
  • current-slot . Bundan sonra önyüklenecek yuva son ekini döndürür.
  • slot-count Kullanılabilir yuvaların sayısını temsil eden bir tamsayı döndürür. Şu anda iki yuva desteklenmektedir, dolayısıyla bu değer 2 .
  • slot-successful:<slot-suffix> . Belirtilen yuva başarıyla önyükleme olarak işaretlendiyse "evet", aksi takdirde "hayır" döndürür.
  • slot-unbootable:<slot-suffix> . Belirtilen yuva önyüklenemez olarak işaretlendiyse "evet", aksi takdirde "hayır" döndürür.
  • slot-retry-count . Belirli bir 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şturma

OTA paketi araçları, A/B olmayan cihazlar için verilen komutlarla aynı komutları izler. A/B hedefi için yapı değişkenleri tanımlanarak target_files.zip dosyası oluşturulmalıdır. OTA paket araçları, paketleri A/B güncelleyici biçiminde 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 ön eki ( system veya boot gibi) ve yuva başına son eki (örneğin _a ) 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 bölüm bootloader_a ve booloader_b dahil edilmişse ( _a ve _b yuva sonekleridir), ü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üncellemeler sırasında, mevcut yuvadaki ikili veriler, yeni yuvadaki verileri oluşturmak için kullanılır. Herhangi bir değişiklik, güncelleme işlemi sırasında yeni yuva verilerinin doğrulanamaması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, yükleme sonrası adımını her güncellenen bölüm için 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 şeklindedir (RAM disk kullanmıyorsanız). Ek olarak, mount(2) sistem çağrısına iletilecek dosya sistemi tipini belirtin. Aşağıdakileri ürün veya cihaz .mk dosyalarına ekleyin (varsa):

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

derleme

Uygulamalar, yeni sistem görüntüsü ile 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ğıdakini ekleyin:

  1. Derleme betiğinin ve ikili dosyaların derlenip sistem görüntüsüne dahil edildiğinden emin olmak için yapıya yerel bileşenleri dahil edin.
      # A/B OTA dexopt package
      PRODUCT_PACKAGES += otapreopt_script
    
  2. Derleme betiğini, yükleme sonrası bir 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
    

Önceden seçilmiş dosyaları kullanılmayan ikinci sistem bölümüne kurma konusunda yardım için, DEX_PROPT dosyalarının ilk önyükleme kurulumuna bakın.