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

Android 11, Genel Çekirdek Görüntüsü (GKI) kavramını tanıttı. Kolayca GKI ile keyfi bir cihaza önyükleme etkinleştirmek için Android 11 cihazlar 3. sürümde önyükleme görüntü başlık sürüm 3'ü kullanabilirsiniz tüm satıcıya özgü bilgiler dışında çarpanlarına boot bölümü ve yeni bir nakledilerek vendor_boot bölümü. 5.4 Linux çekirdeği üzerinde Android 11 ile bir ARM64 cihaz fırlatma desteklemelidir vendor_boot bölümü ve güncellenmiş boot GKI ile test geçmek bölümü format.

Android 12 cihazlar birden fazla satıcı Ramdiskin dahil önyükleme görüntü başlık sürümü 4, destekleri kullanabilirsiniz vendor_boot bölüm. Birden çok satıcı ramdisk parçası, satıcı ramdisk 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 açıklamak için bir satıcı ramdisk tablosu kullanılır.

bölme yapısı

Satıcı önyükleme bölümü, sanal A/B ile A/B'dir ve Android Verified Boot tarafından korunur.

Sürüm 3

Bölüm, bir başlık, satıcı ramdiski 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 (s sayfa) p = (dtb_size + page_size - 1) / page_size

Sürüm 4

Bölüm bir başlıktan, satıcı ramdisk bölümünden (birleştirilmiş tüm satıcı ramdisk parçalarından oluşur), aygıt ağacı blobundan (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ı ramdisk parçaları (o sayfalar) o = (vendor_ramdisk_size + page_size - 1) / page_size
DTB (s 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ı önyükleme bölümü başlığının içeriği öncelikle oradan taşındı oldu verilerden oluşur önyükleme görüntü başlığında . Ayrıca satıcı 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 belirtmektedir ramdisk tipi, olası değerler şunlardır:
    • VENDOR_RAMDISK_TYPE_NONE değeri belirlenmemiş olduğunu gösterir.
    • VENDOR_RAMDISK_TYPE_PLATFORM Ramdisk'leri platforma özel bit içerir. Önyükleyici bunları her zaman belleğe yüklemelidir.
    • VENDOR_RAMDISK_TYPE_RECOVERY Ramdisk'leri kurtarma kaynaklarını içermektedir. Önyükleyici, kurtarma işlemine başlarken bunları belleğe yüklemelidir.
    • VENDOR_RAMDISK_TYPE_DLKM Ramdisk'leri dinamik yüklenebilir kernel modüllerini içermektedir.
  • ramdisk_name ramdisk'in bir benzersiz addır.
  • board_id satıcı tanımlanmış donanım tanımlayıcılarının bir vektördü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 için önyükleyicinin hem önyükleme hem de satıcı önyükleme bölümlerine erişmesi gerekir. .

Bootloader hemen satıcı ramdisk aşağıdaki belleğe jenerik ramdiski yükleyebilmelidir (CPIO, Gzip ve lz4 formatları birleştirme destekliyorsa bu tür). Genel ramdisk görüntüsünü sayfa hizalamayın veya bellekteki satıcı ramdisk'inin sonu ile arasına başka bir boşluk koymayın. Çekirdek açar sonra, bir içine birleştirilmiş dosya ayıklar initramfs , satıcı ramdiskin dosya yapısı üzerinde genel bir ramdiski Kaplanmış olan bir dosya yapısında hangi sonuçları.

Jenerik ramdisk ve satıcı ramdiski birleştirildiğinden, aynı biçimde 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 cihaz, lz4 ile sıkıştırılmış bir satıcı ramdisk'i kullanmalıdır. Bunun için yapılandırma aşağıda gösterilmiştir.

Bootconfig desteklemek için bootloader gereksinimleri üzerinde açıklanmıştır Uygulama Bootconfig sayfa.

Birden çok satıcı ramdiski (sürüm 4)

Önyükleme görüntü başlık sürüm 4 ile bootloader bir alt ya da yüke satıcı Ramdisk'in tüm seçebilirsiniz initramfs önyükleme işlemi sırasında. Satıcı ramdisk tablosu, her bir ramdisk'in meta verilerini içerir ve hangi ramdisklerin yükleneceğine karar vermede önyükleyiciye yardımcı olabilir. Önyükleyici, genel ramdisk en son yüklendiği sürece, seçilen satıcı ramdisklerini yükleme sırasına karar verebilir.

Örneğin, bootloader tipi yükleme satıcı ramdiskleri atlayabilirsiniz VENDOR_RAMDISK_TYPE_RECOVERY tipi Ramdisk'leri yüzden sadece satıcı, konserve kaynaklarına Normal önyükleme sırasında VENDOR_RAMDISK_TYPE_PLATFORM ve VENDOR_RAMDISK_TYPE_DLKM belleğe yüklenir. Öte yandan, tipi satıcı Ramdisk'leri VENDOR_RAMDISK_TYPE_PLATFORM , VENDOR_RAMDISK_TYPE_RECOVERY ve VENDOR_RAMDISK_TYPE_DLKM kurtarma moduna önyükleme sırasında belleğe yüklenir.

Alternatif olarak, önyükleyici satıcı ramdisk tablosunu yok sayabilir ve tüm satıcı ramdisk bölümünü yükleyebilir. İçinde satıcı ramdiskin parçaların hepsi yüklenirken yaptığı gibi bu aynı etkiye sahiptir vendor_boot bölümü.

Destek oluştur

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

  • Ayar BOARD_BOOT_HEADER_VERSION için 3 veya daha fazlası.

  • Set BOARD_RAMDISK_USE_LZ4 için true Cihazınızın GKI uyumlu ise, ya da başka türlü bir lz4 sıkıştırılmış jenerik ramdiske kullanıyorsa.

  • Set BOARD_VENDOR_BOOTIMAGE_PARTITION_SIZE satıcı ramdisk'in devam etmeli çekirdek modüllerini dikkate cihazınız için uygun bir boyuta.

  • Güncelleme AB_OTA_PARTITIONS dahil etmek vendor_boot ve cihazdaki OTA bölümleri herhangi satıcıya özgü listeleri.

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

İçinde birden fazla tedarikçi firma ramdiskleri dahil etmek için vendor_boot :

  • Set BOARD_BOOT_HEADER_VERSION için 4 .
  • Ayar BOARD_VENDOR_RAMDISK_FRAGMENTS mantıksal satıcı ramdisk fragmanı adları listesine dahil edilecek vendor_boot .

  • Bir önceden oluşturulmuş satıcı ramdisk set eklemek için BOARD_VENDOR_RAMDISK_FRAGMENT.$(vendor_ramdisk).PREBUILT önceden oluşturulmuş dosya yoluna.

  • Bir DLKM satıcı ramdisk set eklemek için BOARD_VENDOR_RAMDISK_FRAGMENT.$(vendor_ramdisk).KERNEL_MODULE_DIRS çekirdek modülü dizin listesine dahil edilecek.

  • Set BOARD_VENDOR_RAMDISK_FRAGMENT.$(vendor_ramdisk).MKBOOTIMG_ARGS için mkbootimg argümanlar. Bunlar --board_id[0-15] ve --ramdisk_type satıcı ramdisk fragmanı için değişkenleri. DLKM satıcı ramdiske için, varsayılan --ramdisk_type olacağını DLKM aksi belirtilmemişse eğer.

Tek başına olarak kurtarma kaynaklarını oluşturmak için recovery içinde ramdisk vendor_boot :

  • Set BOARD_BOOT_HEADER_VERSION için 4 .
  • Set BOARD_MOVE_RECOVERY_RESOURCES_TO_VENDOR_BOOT için true .
  • Set BOARD_INCLUDE_RECOVERY_RAMDISK_IN_VENDOR_BOOT için true .
  • Bu kimin bir satıcı ramdiskin parçasını ekler ramdisk_name olan recovery ve ramdisk_type olan VENDOR_RAMDISK_TYPE_RECOVERY . Ramdiskin sonra altında yüklü dosyalardır tüm kurtarma dosyaları içerir $(TARGET_RECOVERY_ROOT_OUT) .

mkbootimg argümanlar

Argüman Açıklama
--ramdisk_type Ramdisk tipi, biri olabilir NONE , PLATFORM , RECOVERY veya DLKM .
--board_id[0-15] Belirtin board_id için, varsayılan vektör 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

Elde edilen vendor_boot iki satıcı ramdisk fragmanlarını ihtiva edecektir. İlki DLKM dizini içeriyor "varsayılan" ramdiskin olduğu baz ve dosyaların geri kalanını $(TARGET_VENDOR_RAMDISK_OUT) . İkincisi ise dlkm_foobar DLKM dizinleri içeren ramdisk, foo ve bar ve --ramdisk_type için varsayılan DLKM .