Tedarikçi firma önyükleme bölümleri

Android 11, Genel Çekirdek Görüntüsü (GKI) kavramını kullanıma sundu. Android 11 cihazlar, GKI ile rastgele bir cihazın başlatılmasını etkinleştirmek için önyükleme resmi üstbilgisi sürüm 3'ü kullanabilir. 3. sürümde, tedarikçiye özgü tüm bilgiler boot bölümünden çıkarılır ve yeni bir vendor_boot bölümüne taşınır. 5.4 Linux çekirdeğinde Android 11 ile kullanıma sunulan ARM64 cihazların, GKI ile testi geçmesi için vendor_boot bölümünü ve güncellenmiş boot bölüm biçimini desteklemesi gerekir.

Android 12 cihazlar, vendor_boot bölümüne birden fazla tedarikçi firma ramdiski eklemeyi destekleyen önyükleme resmi üstbilgisi sürüm 4'ü kullanabilir. Birden fazla tedarikçi firma ramdisk parçası, tedarikçi firma ramdisk bölümünde birbiri ardına birleştirilir. Tedarikçi firma ramdiski bölümünün düzenini ve her tedarikçi firma ramdiski parçasının meta verilerini açıklamak için tedarikçi firma ramdiski tablosu kullanılır.

Bölüm yapısı

Tedarikçi firma önyükleme bölümü, sanal A/B ile A/B'ye ayrılır ve Android Doğrulanmış Önyükleme ile korunur.

Sürüm 3

Bölüm bir başlık, tedarikçi ramdisk'i ve cihaz ağacı blob'undan (DTB) oluşur.

Bölüm Sayfa sayısı
Tedarikçi firma önyükleme üstbilgisi (n sayfa) n = (2112 + page_size - 1) / page_size
Tedarikçi firma ramdisk'i (o sayfa) o = (vendor_ramdisk_size + page_size - 1) / page_size
DTB (p sayfa) p = (dtb_size + page_size - 1) / page_size

Sürüm 4

Bölüm bir başlıktan, tedarikçi ramdisk bölümünden (tüm tedarikçi ramdisk parçalarının birleştirilmesiyle oluşur), cihaz ağacı blob'undan (DTB) ve tedarikçi ramdisk tablosundan oluşur.

Bölüm Sayfa sayısı
Tedarikçi firma önyükleme üstbilgisi (n sayfa) n = (2128 + page_size - 1) / page_size
Satıcı ramdiski parçaları (o sayfa) o = (vendor_ramdisk_size + page_size - 1) / page_size
DTB (p sayfa) p = (dtb_size + page_size - 1) / page_size
Satıcı ramdisk tablosu (q sayfaları) q = (vendor_ramdisk_table_size + page_size - 1) / page_size
Bootconfig (r sayfaları) r = (bootconfig_size + page_size - 1) / page_size

Tedarikçi firma önyükleme üstbilgisi

Tedarikçi firma önyükleme bölümü üstbilgisinin içeriği, temel olarak önyükleme resmi üstbilgisinin üstbilgisine taşınan verilerden oluşur. Ayrıca tedarikçi firma ramdisk'i hakkında bilgi içerir.

Sürüm 3

struct vendor_boot_img_hdr_v3
{
#define VENDOR_BOOT_MAGIC_SIZE 8
    uint8_t magic[VENDOR_BOOT_MAGIC_SIZE];
    uint32_t header_version;
    uint32_t page_size;           /* flash page size we assume */

    uint32_t kernel_addr;         /* physical load addr */
    uint32_t ramdisk_addr;        /* physical load addr */

    uint32_t vendor_ramdisk_size; /* size in bytes */

#define VENDOR_BOOT_ARGS_SIZE 2048
    uint8_t cmdline[VENDOR_BOOT_ARGS_SIZE];

    uint32_t tags_addr;           /* physical addr for kernel tags */

#define VENDOR_BOOT_NAME_SIZE 16
    uint8_t name[VENDOR_BOOT_NAME_SIZE]; /* asciiz product name */
    uint32_t header_size;         /* size of vendor boot image header in
                                   * bytes */
    uint32_t dtb_size;            /* size of dtb image */
    uint64_t dtb_addr;            /* physical load address */

};

Sürüm 4

struct vendor_boot_img_hdr_v4
{
#define VENDOR_BOOT_MAGIC_SIZE 8
    uint8_t magic[VENDOR_BOOT_MAGIC_SIZE];
    uint32_t header_version;
    uint32_t page_size;           /* flash page size we assume */

    uint32_t kernel_addr;         /* physical load addr */
    uint32_t ramdisk_addr;        /* physical load addr */

    uint32_t vendor_ramdisk_size; /* size in bytes */

#define VENDOR_BOOT_ARGS_SIZE 2048
    uint8_t cmdline[VENDOR_BOOT_ARGS_SIZE];

    uint32_t tags_addr;           /* physical addr for kernel tags */

#define VENDOR_BOOT_NAME_SIZE 16
    uint8_t name[VENDOR_BOOT_NAME_SIZE]; /* asciiz product name */
    uint32_t header_size;         /* size of vendor boot image header in
                                   * bytes */
    uint32_t dtb_size;            /* size of dtb image */
    uint64_t dtb_addr;            /* physical load address */

    uint32_t vendor_ramdisk_table_size; /* size in bytes for the vendor ramdisk table */
    uint32_t vendor_ramdisk_table_entry_num; /* number of entries in the vendor ramdisk table */
    uint32_t vendor_ramdisk_table_entry_size; /* size in bytes for a vendor ramdisk table entry */
    uint32_t bootconfig_size; /* size in bytes for the bootconfig section */
};

#define VENDOR_RAMDISK_TYPE_NONE 0
#define VENDOR_RAMDISK_TYPE_PLATFORM 1
#define VENDOR_RAMDISK_TYPE_RECOVERY 2
#define VENDOR_RAMDISK_TYPE_DLKM 3

struct vendor_ramdisk_table_entry_v4
{
    uint32_t ramdisk_size; /* size in bytes for the ramdisk image */
    uint32_t ramdisk_offset; /* offset to the ramdisk image in vendor ramdisk section */
    uint32_t ramdisk_type; /* type of the ramdisk */
#define VENDOR_RAMDISK_NAME_SIZE 32
    uint8_t ramdisk_name[VENDOR_RAMDISK_NAME_SIZE]; /* asciiz ramdisk name */

#define VENDOR_RAMDISK_TABLE_ENTRY_BOARD_ID_SIZE 16
    // Hardware identifiers describing the board, soc or platform which this
    // ramdisk is intended to be loaded on.
    uint32_t board_id[VENDOR_RAMDISK_TABLE_ENTRY_BOARD_ID_SIZE];
};
  • vendor_ramdisk_size, tüm tedarikçi ramdisk parçalarının toplam boyutudur.
  • ramdisk_type, ramdisk'in türünü belirtir. Olası değerler şunlardır:
    • VENDOR_RAMDISK_TYPE_NONE, değerin belirtilmediğini gösterir.
    • VENDOR_RAMDISK_TYPE_PLATFORM ramdisk'leri platforma özgü bitler içerir. Önyükleyici bunları her zaman belleğe yüklemelidir.
    • VENDOR_RAMDISK_TYPE_RECOVERY ramdisk'leri kurtarma kaynaklarını içerir. Bootloader, kurtarma moduna önyükleme yaparken bunları belleğe yüklemelidir.
    • VENDOR_RAMDISK_TYPE_DLKM ramdisk'leri dinamik olarak yüklenebilir çekirdek modülleri içerir.
  • ramdisk_name, ramdisk'in benzersiz adıdır.
  • board_id, tedarikçi firma tarafından tanımlanan donanım tanımlayıcılarının bir vektörüdür.

Bootloader desteği

Tedarikçi firma önyükleme bölümü, daha önce önyükleme bölümünde bulunan bilgileri (ör. flash sayfa boyutu, çekirdek, ramdisk yükleme adresleri, DTB'nin kendisi) içerdiğinden, önyükleme işlemini tamamlayacak yeterli veriye sahip olmak için önyükleme yükleyicinin hem önyükleme hem de tedarikçi firma önyükleme bölümlerine erişmesi gerekir.

Önyükleyici, tedarikçi ramdisk'inden sonra genel ramdisk'i hemen belleğe yüklemelidir (CPIO, Gzip ve lz4 biçimleri bu tür bir birleştirme işlemini destekler). Genel ramdisk resmini sayfaya hizalamayın veya bu resim ile bellekteki tedarikçi ramdisk'in sonu arasına başka bir alan eklemeyin. Çekirdek, sıkıştırılmış dosyayı initramfs olarak ayıklayarak tedarikçi firmanın ramdisk dosya yapısının üzerine yerleştirilmiş genel bir ramdisk dosya yapısı oluşturur.

Genel ramdisk ve tedarikçi ramdiski birleştirildiğinden aynı biçimde olmalıdırlar. GKI önyükleme görüntüsü lz4 sıkıştırılmış genel bir ramdisk kullandığından, GKI uyumlu bir cihaz lz4 sıkıştırılmış bir tedarikçi ramdiski kullanmalıdır. Bunun için yapılandırmayı aşağıda görebilirsiniz.

bootconfig'i desteklemek için bootloader gereksinimleri bootconfig'i uygulama bölümünde açıklanmıştır.

Birden fazla satıcının ramdisk'leri (4. sürüm)

Önyükleme resmi başlığı sürüm 4 ile önyükleme yükleyici, önyükleme sırasında initramfs olarak yüklenecek tedarikçi ramdisk'lerinin bir alt kümesini veya tamamını seçebilir. Tedarikçi firma ramdisk tablosu, her ramdisk'in meta verilerini içerir ve hangi ramdisk'lerin yükleneceğine karar verirken önyükleyiciye yardımcı olabilir. Genel ramdisk en son yüklenecek şekilde, önyükleme programı seçilen tedarikçi ramdisklerinin yüklenme sırasına karar verebilir.

Örneğin, önyükleyici, kaynakları korumak için normal önyükleme sırasında VENDOR_RAMDISK_TYPE_RECOVERY türündeki tedarikçi ramdisk'lerini yüklemeyebilir. Bu nedenle, belleğe yalnızca VENDOR_RAMDISK_TYPE_PLATFORM ve VENDOR_RAMDISK_TYPE_DLKM türündeki tedarikçi ramdisk'leri yüklenir. Öte yandan, VENDOR_RAMDISK_TYPE_PLATFORM, VENDOR_RAMDISK_TYPE_RECOVERY ve VENDOR_RAMDISK_TYPE_DLKM türündeki tedarikçi ramdisk'leri, kurtarma modunda önyükleme yapılırken belleğe yüklenir.

Alternatif olarak, önyükleme programı tedarikçi ramdisk tablosunu yok sayabilir ve tedarikçi ramdisk bölümünün tamamını yükleyebilir. Bu, tedarikçi ramdisk parçalarının tümünün vendor_boot bölümüne yüklenmesi ile aynı etkiye sahiptir.

Destek oluşturma

Bir cihaz için tedarikçi firma önyükleme desteğini uygulamak üzere:

  • BOARD_BOOT_HEADER_VERSION öğesini 3 veya daha yüksek bir değere ayarlayın.

  • Cihazınız GKI uyumluysa veya lz4 sıkıştırılmış genel bir ramdisk kullanıyorsa BOARD_RAMDISK_USE_LZ4 değerini true olarak ayarlayın.

  • Tedarikçi firma ramdisk'ine yerleştirilmesi gereken çekirdek modüllerini göz önünde bulundurarak BOARD_VENDOR_BOOTIMAGE_PARTITION_SIZE değerini cihazınız için uygun bir boyuta ayarlayın.

  • AB_OTA_PARTITIONS öğesini, vendor_boot ve cihazdaki OTA bölümlerinin tedarikçiye özel listelerini içerecek şekilde güncelleyin.

  • Cihazınızı boot bölümüne değil, vendor_boot bölümüne fstab kopyalayın./first_stage_ramdisk Örneğin, $(LOCAL_PATH)/fstab.hardware:$(TARGET_COPY_OUT_VENDOR_RAMDISK)/first_stage_ramdisk/fstab.$(PRODUCT_PLATFORM).

vendor_boot dosyasına birden fazla satıcı ramdisk'i eklemek için:

  • BOARD_BOOT_HEADER_VERSION değerini 4 olarak ayarlayın.
  • BOARD_VENDOR_RAMDISK_FRAGMENTS değerini, vendor_boot içine eklenecek mantıksal tedarikçi ramdiski parça adlarının listesi olarak ayarlayın.

  • Önceden oluşturulmuş bir tedarikçi ramdisk'i eklemek için BOARD_VENDOR_RAMDISK_FRAGMENT.$(vendor_ramdisk).PREBUILT değerini önceden oluşturulmuş yola ayarlayın.

  • DLKM tedarikçisi ramdisk eklemek için BOARD_VENDOR_RAMDISK_FRAGMENT.$(vendor_ramdisk).KERNEL_MODULE_DIRS değerini, dahil edilecek çekirdek modülü dizinlerinin listesine ayarlayın.

  • BOARD_VENDOR_RAMDISK_FRAGMENT.$(vendor_ramdisk).MKBOOTIMG_ARGS bağımsız değişkenini mkbootimg bağımsız değişkenleri olarak ayarlayın. Bunlar, tedarikçi ramdisk parçası için --board_id[0-15] ve --ramdisk_type bağımsız değişkenleridir. DLKM tedarikçisi ramdisk için, aksi belirtilmediyse varsayılan --ramdisk_type DLKM olur.

Kurtarma kaynaklarını vendor_boot'da bağımsız bir recovery ramdisk olarak oluşturmak için:

  • BOARD_BOOT_HEADER_VERSION değerini 4 olarak ayarlayın.
  • BOARD_MOVE_RECOVERY_RESOURCES_TO_VENDOR_BOOT değerini true olarak ayarlayın.
  • BOARD_INCLUDE_RECOVERY_RAMDISK_IN_VENDOR_BOOT değerini true olarak ayarlayın.
  • Bu işlem, ramdisk_name değeri recovery ve ramdisk_type değeri VENDOR_RAMDISK_TYPE_RECOVERY olan bir tedarikçi ramdisk parçası ekler. Ardından, ramdisk tüm kurtarma dosyalarını içerir. Bu dosyalar, $(TARGET_RECOVERY_ROOT_OUT) altında yüklenir.

mkbootimg bağımsız değişkenleri

Bağımsız değişken Açıklama
--ramdisk_type Ramdisk türü NONE, PLATFORM, RECOVERY veya DLKM olabilir.
--board_id[0-15] board_id vektörünü belirtin. Varsayılan olarak 0 olur.

Aşağıda örnek bir yapılandırma verilmiştir:

BOARD_KERNEL_MODULE_DIRS := foo bar baz
BOARD_BOOT_HEADER_VERSION := 4
BOARD_VENDOR_RAMDISK_FRAGMENTS := dlkm_foobar
BOARD_VENDOR_RAMDISK_FRAGMENT.dlkm_foobar.KERNEL_MODULE_DIRS := foo bar
BOARD_VENDOR_RAMDISK_FRAGMENT.dlkm_foobar.MKBOOTIMG_ARGS := --board_id0 0xF00BA5 --board_id1 0xC0FFEE

Sonuç olarak elde edilen vendor_boot, iki tedarikçi ramdisk parçası içerir. Bunlardan ilki, DLKM dizini baz ve $(TARGET_VENDOR_RAMDISK_OUT) içindeki diğer dosyaları içeren "varsayılan" ramdisk'tir. İkincisi, DLKM dizinleri foo ve bar'yi içeren dlkm_foobar ramdisk'tir ve --ramdisk_type varsayılan olarak DLKM olarak ayarlanır.