A/B Güncellemelerini Uygulama

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

Önyükleme denetimi HAL'i uygulama

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

Ayrıca aşağıda gösterilen durum makinesini de uygulamalısınız:

Ş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):
    • Ramdisk olmadan önyükleme yapıyorsanız ve "kurtarma olarak önyükleme" kullanıyorsanız, Cherrypick Android-review.googlesource.com/#/c/158491/ .
    • dm- verity'yi ramdisk olmadan ayarlamak için, Cherrypick Android-review.googlesource.com/#/q/status:merged+project:kernel/common+branch:Android-3.18+topic:A_B_Changes_3.18 .
  2. Çekirdek komut satırı bağımsız değişkenlerinin aşağıdaki ek 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ğrulama tablosu imzasını doğrulamak için kullanılan ortak 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 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ştirilmesi gerekir):
      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 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 .

Yapı değişkenlerini ayarlama

A/B özellikli önyükleyiciler aşağıdaki yapı 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 bakın. İsteğe bağlı olarak, Derleme bölümünde açıklanan yükleme sonrası (ancak yeniden başlatma öncesi) dex2oat adımını gerçekleştirebilirsiniz.
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ü şimdi indirilen OTA paketi için kullanılıyor ve kurtarma görüntüsü kodu önyükleme bölümünde. 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ı: Hangi güncellemeleri uygulamak istediğinize bağlı olarak ne kadar büyük olması gerektiği. 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ıyorsunuz) ve A/B akışı ile uygulamadan önce tüm OTA paketini indirmeye gerek yoktur.

Kurtarma

Kurtarma RAM diski artık boot.img dosyasında bulunur. Kurtarmaya 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. Fabrika verilerine sıfırlama ve güncelleme paketlerinin yandan yüklenmesini uygulamak için kullanılan bir kurtarma modu hala vardır ("kurtarma" adının geldiği yer burasıdır). Kurtarma modu için 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 ramdiski 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ü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 monte edilecektir.

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

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

Varsayılan olarak, fastboot bir A/B aygıtındaki geçerli yuvayı yanıp söner. Güncelleme paketi diğer, geçerli olmayan yuva için de görüntüler içeriyorsa, fastboot bu görüntüleri de yanıp söner. Kullanılabilir 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 geçirilen yuvayı flaş etmesini isteyin.
  • --set-active [ SLOT ] . Yuvayı 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 uygularsa, mevcut etkin yuvayı verilen yuvaya ayarlayan set_active <slot> komutunu desteklemesi gerekir (bu aynı zamanda o yuva için başlatılamaz 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 . Sonrakinden başlatılacak yuva son ekini döndürür.
  • slot-count . Kullanılabilir yuva sayısını temsil eden bir tamsayı döndürür. Şu anda iki yuva desteklenmektedir, bu nedenle 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 başlatılamaz olarak işaretlenmişse "evet", aksi takdirde "hayır" döndürür.
  • slot-retry-count . Verilen 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 çalıştırın.

OTA paketleri oluşturma

OTA paket araçları , A/B olmayan aygıtlar için komutlarla aynı komutları izler. target_files.zip dosyası, A/B hedefi için yapı değişkenleri tanımlanarak oluşturulmalıdır. OTA paket araçları, A/B güncelleyici formatında 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 (ö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, bootloader_a ve booloader_b bölümleri çifti dahil edilmişse ( _a ve _b yuva sonekleridir), ürün veya kart konfigürasyonunda 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, güncelleme işlemi sırasında yeni yuva verilerinin 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, yükleme sonrası adımını güncellenen her bölüm için farklı şekilde yapılandırabilirsiniz. /system/usr/bin/postinst bulunan bir programı yeni bir görüntüde çalıştırmak için, sistem bölümünde dosya sisteminin kök dizinine göre yolu belirtin.

Örneğin, usr/bin/postinst , system/usr/bin/postinst (RAM disk kullanmıyorsa). Ek olarak, mount(2) sistem çağrısına iletilecek dosya sistemi türünü 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

Güvenlik nedeniyle, system_server tam zamanında (JIT) derlemeyi kullanamaz. Bu, system_server ve bağımlılıkları için minimumda önceden odex dosyalarını derlemeniz gerektiği anlamına gelir; başka bir şey isteğe bağlıdır.

Uygulamaları arka planda derlemek için ürünün cihaz yapılandırmasına aşağıdakileri eklemelisiniz (ürünün device.mk dosyasında):

  1. Derleme betiğinin 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 dahil edin.
      # 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ünde önceden seçilmiş dosyaların yüklenmesiyle ilgili yardım için, DEX_PReoPT dosyalarının ilk önyükleme kurulumuna bakın.