Satıcı Önyükleme Bölümleri

Android 11, Genel Çekirdek Görüntüsü (GKI) kavramını tanıttı. GKI ile rastgele bir cihazın kolayca önyüklenmesini sağlamak için Android 11 cihazları, önyükleme görüntüsü üstbilgisi sürüm 3'ü kullanabilir. Sürüm 3'te, satıcıya ö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 başlatılan bir ARM64 cihazının GKI ile testi geçebilmesi 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 satıcı ramdiskinin dahil edilmesini destekleyen önyükleme görüntüsü üstbilgisi sürüm 4'ü kullanabilir. Birden fazla satıcının ramdisk parçası, satıcının ramdiski bölümünde birbiri ardına birleştirilir. Satıcı ramdisk bölümünün düzenini ve her satıcı ramdisk parçasının meta verilerini tanımlamak için bir satıcı ramdisk tablosu kullanılır.

Bölüm yapısı

Satıcının önyükleme bölümü sanal A/B ile A/B'dir ve Android Doğrulanmış Önyükleme tarafından korunur.

Sürüm 3

Bölüm bir başlıktan, satıcı ramdiskinden ve aygıt ağacı bloğundan (DTB) oluşur.

Bölüm Sayfa sayısı
Satıcı önyükleme başlığı (n sayfa) n = (2112 + page_size - 1) / page_size
Satıcı ramdiski (o sayfalar) 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, satıcı ramdiski bölümünden (birleştirilmiş tüm satıcı ramdisk parçalarından oluşur), aygıt ağacı bloğundan (DTB) ve satıcı ramdisk tablosundan oluşur.

Bölüm Sayfa sayısı
Satıcı önyükleme başlığı (n sayfa) n = (2128 + page_size - 1) / page_size
Satıcının ramdisk parçaları (o sayfalar) 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 sayfa) q = (vendor_ramdisk_table_size + page_size - 1) / page_size
Bootconfig (r sayfaları) r = (bootconfig_size + page_size - 1) / page_size

Satıcı önyükleme başlığı

Satıcının önyükleme bölümü başlığının içeriği, esas olarak, önyükleme görüntüsü başlığından oraya taşınan verilerden oluşur. Ayrıca satıcının ramdiski 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 satıcı ramdisk parçalarının toplam boyutudur.
  • ramdisk_type , ramdiskin türünü belirtir; olası değerler şunlardır:
    • VENDOR_RAMDISK_TYPE_NONE değerin belirtilmediğini gösterir.
    • VENDOR_RAMDISK_TYPE_PLATFORM ramdiskleri platforma özel bitler içerir. Önyükleyicinin bunları her zaman belleğe yüklemesi gerekir.
    • VENDOR_RAMDISK_TYPE_RECOVERY ramdiskleri kurtarma kaynaklarını içerir. Kurtarma işlemine önyükleme yaparken önyükleyicinin bunları belleğe yüklemesi gerekir.
    • VENDOR_RAMDISK_TYPE_DLKM ramdiskleri dinamik yüklenebilir çekirdek modülleri içerir.
  • ramdisk_name , ramdiskin benzersiz bir adıdır.
  • board_id , satıcı tarafından tanımlanan donanım tanımlayıcılarının bir vektörüdür.

Önyükleyici desteği

Satıcı önyükleme bölümü, önyükleme bölümünde önceden var olan bilgileri (flash sayfa boyutu, çekirdek, ramdisk yükleme adresleri, DTB'nin kendisi gibi) içerdiğinden, önyüklemeyi tamamlamak için yeterli veriye sahip olmak amacıyla önyükleyicinin hem önyükleme hem de satıcı önyükleme bölümlerine erişmesi gerekir. .

Önyükleyicinin, satıcının ramdiskinden hemen sonra genel ramdiski belleğe yüklemesi gerekir (CPIO, Gzip ve lz4 formatları bu tür birleştirmeyi destekler). Genel ramdisk görüntüsünü sayfa hizalamayın veya bellekteki satıcının ramdiskinin sonu ile arasına başka bir boşluk koymayın. Çekirdek sıkıştırılmış dosyayı açtıktan sonra, birleştirilmiş dosyayı initramfs dosyasına çıkarır; bu, satıcının ramdisk dosya yapısının üzerine yerleştirilmiş genel bir ramdisk olan bir dosya yapısıyla sonuçlanır.

Genel ramdisk ve satıcının ramdiski birleştirildiği için aynı formatta olmaları gerekir. GKI önyükleme görüntüsü, lz4 ile sıkıştırılmış genel bir ramdisk kullanır; bu nedenle, GKI uyumlu bir aygıtın, lz4 ile sıkıştırılmış bir satıcı ramdiski kullanması gerekir. Bunun için konfigürasyon aşağıda gösterilmiştir.

Önyükleme yapılandırmasını desteklemek için önyükleyici gereksinimleri, Önyükleme Yapılandırmasının Uygulanması sayfasında açıklanmaktadır.

Çoklu satıcı ramdiskleri (sürüm 4)

Önyükleme görüntüsü başlığı sürüm 4 ile, önyükleyici, önyükleme süresi sırasında initramfs olarak yüklemek üzere satıcının ramdisklerinin bir alt kümesini veya tamamını seçebilir. Satıcının ramdisk tablosu her bir ramdiskin meta verilerini içerir ve önyükleyicinin hangi ramdisklerin yükleneceğine karar vermesine yardımcı olabilir. Önyükleyici, genel ramdisk en son yüklendiği sürece seçilen satıcının 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 satıcı ramdisklerinin yüklenmesini atlayabilir, böylece yalnızca VENDOR_RAMDISK_TYPE_PLATFORM ve VENDOR_RAMDISK_TYPE_DLKM türündeki satıcı ramdiskleri belleğe yüklenir. Öte yandan, VENDOR_RAMDISK_TYPE_PLATFORM , VENDOR_RAMDISK_TYPE_RECOVERY ve VENDOR_RAMDISK_TYPE_DLKM türündeki satıcı ramdiskleri, kurtarma modunda önyükleme yapılırken belleğe yüklenir.

Alternatif olarak, önyükleyici satıcının ramdisk tablosunu yok sayabilir ve satıcının ramdisk bölümünün tamamını yükleyebilir. Bu, vendor_boot bölümündeki tüm satıcı ramdisk parçalarının yüklenmesiyle aynı etkiye sahiptir.

Destek oluşturun

Bir aygıta yönelik satıcı önyükleme desteğini uygulamak için:

  • BOARD_BOOT_HEADER_VERSION 3 veya daha büyük bir değere ayarlayın.

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

  • BOARD_VENDOR_BOOTIMAGE_PARTITION_SIZE öğesini, satıcının ramdiskinde bulunması gereken çekirdek modüllerini göz önünde bulundurarak cihazınız için uygun bir boyuta ayarlayın.

  • AB_OTA_PARTITIONS vendor_boot ve cihazdaki satıcıya özel OTA bölümleri listelerini içerecek şekilde güncelleyin.

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

vendor_boot birden fazla satıcı ramdiski eklemek için:

  • BOARD_BOOT_HEADER_VERSION 4 ayarlayın.
  • BOARD_VENDOR_RAMDISK_FRAGMENTS vendor_boot dahil edilecek mantıksal satıcı ramdisk parçası adlarının listesine ayarlayın.

  • Önceden oluşturulmuş bir satıcı ramdiski eklemek için BOARD_VENDOR_RAMDISK_FRAGMENT.$(vendor_ramdisk).PREBUILT önceden oluşturulmuş dosya yoluna ayarlayın.

  • Bir DLKM satıcı ramdiski eklemek için, dahil edilecek çekirdek modülü dizinleri listesine BOARD_VENDOR_RAMDISK_FRAGMENT.$(vendor_ramdisk).KERNEL_MODULE_DIRS değerini ayarlayın.

  • BOARD_VENDOR_RAMDISK_FRAGMENT.$(vendor_ramdisk).MKBOOTIMG_ARGS mkbootimg argümanlarına ayarlayın. Bunlar satıcının ramdisk parçası için --board_id[0-15] ve --ramdisk_type argümanlarıdır. DLKM satıcısının ramdiski için, aksi belirtilmediği sürece varsayılan --ramdisk_type DLKM olacaktır.

vendor_boot kurtarma kaynaklarını bağımsız bir recovery ramdiski olarak oluşturmak için:

  • BOARD_BOOT_HEADER_VERSION 4 ayarlayın.
  • BOARD_MOVE_RECOVERY_RESOURCES_TO_VENDOR_BOOT değerini true olarak ayarlayın.
  • BOARD_INCLUDE_RECOVERY_RAMDISK_IN_VENDOR_BOOT true olarak ayarlayın.
  • Bu, ramdisk_name recovery ve ramdisk_type VENDOR_RAMDISK_TYPE_RECOVERY olan bir satıcı ramdisk parçası ekler. Ramdisk daha sonra $(TARGET_RECOVERY_ROOT_OUT) altına yüklenen dosyalar olan tüm kurtarma dosyalarını içerir.

mkbootimg argümanları

Argüman Tanım
--ramdisk_type Ramdiskin türü NONE , PLATFORM , RECOVERY veya DLKM olabilir.
--board_id[0-15] board_id vektörünü belirtin; varsayılan değer 0 .

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

Ortaya çıkan vendor_boot iki satıcı ramdisk parçasını içerecektir. Bunlardan ilki, DLKM dizini baz ve $(TARGET_VENDOR_RAMDISK_OUT) içindeki diğer dosyaları içeren "varsayılan" ramdisk'tir. İkincisi, foo ve bar DLKM dizinlerini içeren dlkm_foobar ramdisk'tir ve --ramdisk_type varsayılan olarak DLKM .