বিক্রেতা বুট পার্টিশন

অ্যান্ড্রয়েড ১১ জেনেরিক কার্নেল ইমেজ (GKI) ধারণাটি চালু করেছে। GKI ব্যবহার করে যেকোনো ডিভাইস বুট করার জন্য, অ্যান্ড্রয়েড ১১ ডিভাইসগুলো বুট ইমেজ হেডার ভার্সন ৩ ব্যবহার করতে পারে। ভার্সন ৩-এ, সমস্ত ভেন্ডর-নির্দিষ্ট তথ্য boot পার্টিশন থেকে আলাদা করে একটি নতুন vendor_boot পার্টিশনে স্থানান্তর করা হয়। ৫.৪ লিনাক্স কার্নেলে অ্যান্ড্রয়েড ১১ সহ চালু হওয়া একটি ARM64 ডিভাইসকে GKI দিয়ে পরীক্ষায় উত্তীর্ণ হতে হলে অবশ্যই vendor_boot পার্টিশন এবং আপডেট করা boot পার্টিশন ফরম্যাট সমর্থন করতে হবে।

অ্যান্ড্রয়েড ১২ ডিভাইসগুলো বুট ইমেজ হেডার ভার্সন ৪ ব্যবহার করতে পারে, যা vendor_boot পার্টিশনে একাধিক ভেন্ডর র‍্যামডিস্ক অন্তর্ভুক্ত করা সমর্থন করে। একাধিক ভেন্ডর র‍্যামডিস্ক ফ্র্যাগমেন্ট vendor ramdisk সেকশনে একের পর এক সংযুক্ত করা হয়। ভেন্ডর র‍্যামডিস্ক সেকশনের বিন্যাস এবং প্রতিটি ভেন্ডর র‍্যামডিস্ক ফ্র্যাগমেন্টের মেটাডেটা বর্ণনা করার জন্য একটি ভেন্ডর র‍্যামডিস্ক টেবিল ব্যবহার করা হয়।

বিভাজন কাঠামো

ভেন্ডর বুট পার্টিশনটি ভার্চুয়াল A/B টেস্টের মাধ্যমে যাচাই করা হয় এবং এটি অ্যান্ড্রয়েড ভেরিফায়েড বুট দ্বারা সুরক্ষিত।

সংস্করণ ৩

পার্টিশনটি একটি হেডার, ভেন্ডর র‍্যামডিস্ক এবং ডিভাইস ট্রি ব্লব (DTB) নিয়ে গঠিত।

বিভাগ পৃষ্ঠার সংখ্যা
ভেন্ডর বুট হেডার (n পৃষ্ঠা) n = (2112 + page_size - 1) / page_size
ভেন্ডর র‍্যামডিস্ক (o পৃষ্ঠা) o = (vendor_ramdisk_size + page_size - 1) / page_size
ডিটিবি (পি পৃষ্ঠা) p = (dtb_size + page_size - 1) / page_size

সংস্করণ ৪

পার্টিশনটি একটি হেডার, ভেন্ডর র‍্যামডিস্ক সেকশন (যা সমস্ত ভেন্ডর র‍্যামডিস্ক ফ্র্যাগমেন্ট সংযুক্ত করে গঠিত), ডিভাইস ট্রি ব্লব (DTB), এবং ভেন্ডর র‍্যামডিস্ক টেবিল নিয়ে গঠিত।

বিভাগ পৃষ্ঠার সংখ্যা
ভেন্ডর বুট হেডার (n পৃষ্ঠা) n = (2128 + page_size - 1) / page_size
বিক্রেতার র‍্যামডিস্ক খণ্ডাংশ (o পৃষ্ঠা) o = (vendor_ramdisk_size + page_size - 1) / page_size
ডিটিবি (পি পৃষ্ঠা) p = (dtb_size + page_size - 1) / page_size
বিক্রেতার র‍্যামডিস্ক টেবিল (q পৃষ্ঠা) q = (vendor_ramdisk_table_size + page_size - 1) / page_size
বুটকনফিগ (আর পৃষ্ঠা) r = (bootconfig_size + page_size - 1) / page_size

ভেন্ডর বুট হেডার

ভেন্ডর বুট পার্টিশন হেডারের বিষয়বস্তুতে প্রধানত সেইসব ডেটা থাকে যা বুট ইমেজ হেডার থেকে সেখানে স্থানান্তরিত করা হয়েছে। এতে ভেন্ডর র‍্যামডিস্ক সম্পর্কিত তথ্যও থাকে।

সংস্করণ ৩

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 */

};

সংস্করণ ৪

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 হলো সমস্ত ভেন্ডর র‍্যামডিস্ক ফ্র্যাগমেন্টগুলোর মোট আকার।
  • ramdisk_type র‍্যামডিস্কের ধরণ নির্দেশ করে, এর সম্ভাব্য মানগুলো হলো:
    • VENDOR_RAMDISK_TYPE_NONE নির্দেশ করে যে মানটি অনির্দিষ্ট।
    • VENDOR_RAMDISK_TYPE_PLATFORM র‍্যামডিস্কগুলিতে প্ল্যাটফর্ম-নির্দিষ্ট বিট থাকে। বুটলোডারকে অবশ্যই এগুলি মেমরিতে লোড করতে হবে।
    • VENDOR_RAMDISK_TYPE_RECOVERY র‍্যামডিস্কগুলোতে রিকভারি রিসোর্স থাকে। রিকভারি মোডে বুট করার সময় বুটলোডারকে অবশ্যই এগুলো মেমরিতে লোড করতে হয়।
    • VENDOR_RAMDISK_TYPE_DLKM র‍্যামডিস্কগুলোতে ডাইনামিক লোডেবল কার্নেল মডিউল থাকে।
  • ramdisk_name হলো র‍্যামডিস্কের একটি অনন্য নাম।
  • board_id হলো বিক্রেতা কর্তৃক নির্ধারিত হার্ডওয়্যার শনাক্তকারীগুলির একটি ভেক্টর।

বুটলোডার সমর্থন

যেহেতু ভেন্ডর বুট পার্টিশনে এমন সব তথ্য (যেমন ফ্ল্যাশ পেজ সাইজ, কার্নেল, র‍্যামডিস্ক লোড অ্যাড্রেস, স্বয়ং ডিটিবি) থাকে যা পূর্বে বুট পার্টিশনে বিদ্যমান ছিল, তাই বুটিং সম্পন্ন করার জন্য পর্যাপ্ত ডেটা পেতে বুটলোডারকে অবশ্যই বুট এবং ভেন্ডর উভয় বুট পার্টিশন অ্যাক্সেস করতে হয়।

বুটলোডারকে অবশ্যই ভেন্ডর র‍্যামডিস্কের ঠিক পরেই জেনেরিক র‍্যামডিস্কটি মেমরিতে লোড করতে হবে (CPIO, Gzip, এবং lz4 ফরম্যাটগুলো এই ধরনের সংযোজন সমর্থন করে)। জেনেরিক র‍্যামডিস্ক ইমেজটিকে পেজ অ্যালাইন করবেন না অথবা মেমরিতে এটি এবং ভেন্ডর র‍্যামডিস্কের শেষের মধ্যে অন্য কোনো ফাঁকা স্থান রাখবেন না। কার্নেল ডিকম্প্রেস করার পর, এটি সংযুক্ত ফাইলটিকে একটি initramfs এ এক্সট্র্যাক্ট করে, যার ফলে এমন একটি ফাইল কাঠামো তৈরি হয় যা ভেন্ডর র‍্যামডিস্ক ফাইল কাঠামোর উপর জেনেরিক র‍্যামডিস্কের একটি স্তর হিসেবে থাকে।

যেহেতু জেনেরিক র‍্যামডিস্ক এবং ভেন্ডর র‍্যামডিস্ক সংযুক্ত করা হয়, তাই সেগুলোকে অবশ্যই একই ফরম্যাটে থাকতে হবে। GKI বুট ইমেজ একটি lz4-কম্প্রেসড জেনেরিক র‍্যামডিস্ক ব্যবহার করে, সুতরাং একটি GKI-সম্মত ডিভাইসকে অবশ্যই একটি lz4-কম্প্রেসড ভেন্ডর র‍্যামডিস্ক ব্যবহার করতে হবে। এর কনফিগারেশন নিচে দেখানো হলো।

বুটকনফিগ সমর্থন করার জন্য বুটলোডারের প্রয়োজনীয়তাগুলো "ইমপ্লিমেন্ট বুটকনফিগ" অংশে ব্যাখ্যা করা হয়েছে।

একাধিক বিক্রেতার র‍্যামডিস্ক (সংস্করণ ৪)

বুট ইমেজ হেডার ভার্সন ৪-এর সাহায্যে, বুটলোডার বুট হওয়ার সময় initramfs হিসেবে লোড করার জন্য ভেন্ডর র‍্যামডিস্কগুলোর একটি উপসেট বা সবগুলো নির্বাচন করতে পারে। ভেন্ডর র‍্যামডিস্ক টেবিলে প্রতিটি র‍্যামডিস্কের মেটাডেটা থাকে এবং এটি বুটলোডারকে কোন র‍্যামডিস্কগুলো লোড করতে হবে তা সিদ্ধান্ত নিতে সাহায্য করে। বুটলোডার নির্বাচিত ভেন্ডর র‍্যামডিস্কগুলো লোড করার ক্রম নির্ধারণ করতে পারে, তবে শর্ত হলো জেনেরিক র‍্যামডিস্কটি অবশ্যই শেষে লোড করতে হবে।

উদাহরণস্বরূপ, রিসোর্স সাশ্রয়ের জন্য বুটলোডার সাধারণ বুটের সময় VENDOR_RAMDISK_TYPE_RECOVERY টাইপের ভেন্ডর র‍্যামডিস্ক লোড করা বাদ দিতে পারে, ফলে শুধুমাত্র VENDOR_RAMDISK_TYPE_PLATFORM এবং VENDOR_RAMDISK_TYPE_DLKM টাইপের ভেন্ডর র‍্যামডিস্ক মেমরিতে লোড হয়। অন্যদিকে, রিকভারি মোডে বুট করার সময় VENDOR_RAMDISK_TYPE_PLATFORM , VENDOR_RAMDISK_TYPE_RECOVERY এবং VENDOR_RAMDISK_TYPE_DLKM টাইপের ভেন্ডর র‍্যামডিস্ক মেমরিতে লোড হয়।

বিকল্পভাবে, বুটলোডার ভেন্ডর র‍্যামডিস্ক টেবিলকে উপেক্ষা করে সম্পূর্ণ ভেন্ডর র‍্যামডিস্ক সেকশনটি লোড করতে পারে। এর ফলে vendor_boot পার্টিশনে সমস্ত ভেন্ডর র‍্যামডিস্ক ফ্র্যাগমেন্ট লোড করার মতোই একই প্রভাব পড়ে।

সমর্থন গড়ে তুলুন

একটি ডিভাইসের জন্য ভেন্ডর বুট সাপোর্ট বাস্তবায়ন করতে:

  • BOARD_BOOT_HEADER_VERSION কে 3 বা তার বেশি সেট করুন।

  • আপনার ডিভাইসটি GKI-সম্মত হলে, অথবা অন্যথায় একটি lz4-সংকুচিত জেনেরিক র‍্যামডিস্ক ব্যবহার করলে BOARD_RAMDISK_USE_LZ4 true তে সেট করুন।

  • ভেন্ডর র‍্যামডিস্কে যে কার্নেল মডিউলগুলো অবশ্যই রাখতে হবে, তা বিবেচনা করে আপনার ডিভাইসের জন্য BOARD_VENDOR_BOOTIMAGE_PARTITION_SIZE কে একটি উপযুক্ত আকারে সেট করুন।

  • ডিভাইসে vendor_boot এবং OTA পার্টিশনের যেকোনো বিক্রেতা-নির্দিষ্ট তালিকা অন্তর্ভুক্ত করতে AB_OTA_PARTITIONS আপডেট করুন।

  • আপনার ডিভাইসের fstab ফাইলটি boot পার্টিশনে নয়, বরং vendor_boot পার্টিশনের /first_stage_ramdisk ফোল্ডারে কপি করুন। উদাহরণস্বরূপ, $(LOCAL_PATH)/fstab.hardware:$(TARGET_COPY_OUT_VENDOR_RAMDISK)/first_stage_ramdisk/fstab.$(PRODUCT_PLATFORM)

vendor_boot এ একাধিক ভেন্ডর র‍্যামডিস্ক অন্তর্ভুক্ত করতে:

  • BOARD_BOOT_HEADER_VERSION কে 4 এ সেট করুন।
  • vendor_boot এ অন্তর্ভুক্ত করার জন্য লজিক্যাল ভেন্ডর র‍্যামডিস্ক ফ্র্যাগমেন্টের নামগুলোর একটি তালিকা হিসেবে BOARD_VENDOR_RAMDISK_FRAGMENTS সেট করুন।

  • একটি প্রি-বিল্ট ভেন্ডর র‍্যামডিস্ক যোগ করতে, BOARD_VENDOR_RAMDISK_FRAGMENT.$(vendor_ramdisk).PREBUILT প্রি-বিল্ট পাথে সেট করুন।

  • একটি DLKM ভেন্ডর র‍্যামডিস্ক যোগ করতে, অন্তর্ভুক্ত করার জন্য কার্নেল মডিউল ডিরেক্টরিগুলোর তালিকায় BOARD_VENDOR_RAMDISK_FRAGMENT.$(vendor_ramdisk).KERNEL_MODULE_DIRS সেট করুন।

  • BOARD_VENDOR_RAMDISK_FRAGMENT.$(vendor_ramdisk).MKBOOTIMG_ARGS কে mkbootimg আর্গুমেন্ট হিসেবে সেট করুন। এগুলো হলো ভেন্ডর র‍্যামডিস্ক ফ্র্যাগমেন্টের জন্য --board_id[0-15] এবং --ramdisk_type আর্গুমেন্ট। DLKM ভেন্ডর র‍্যামডিস্কের ক্ষেত্রে, অন্যভাবে নির্দিষ্ট করা না থাকলে ডিফল্ট --ramdisk_type হবে DLKM

vendor_boot এ একটি স্বতন্ত্র recovery র‍্যামডিস্ক হিসেবে রিকভারি রিসোর্স তৈরি করতে:

  • BOARD_BOOT_HEADER_VERSION কে 4 এ সেট করুন।
  • BOARD_MOVE_RECOVERY_RESOURCES_TO_VENDOR_BOOT কে true তে সেট করুন।
  • BOARD_INCLUDE_RECOVERY_RAMDISK_IN_VENDOR_BOOT কে true তে সেট করুন।
  • এটি একটি ভেন্ডর র‍্যামডিস্ক ফ্র্যাগমেন্ট যোগ করে, যার ramdisk_name হলো recovery এবং ramdisk_type হলো VENDOR_RAMDISK_TYPE_RECOVERY । এরপর র‍্যামডিস্কটিতে সমস্ত রিকভারি ফাইল থাকে, যেগুলো $(TARGET_RECOVERY_ROOT_OUT) -এর অধীনে ইনস্টল করা ফাইল।

mkbootimg আর্গুমেন্ট

যুক্তি বর্ণনা
--ramdisk_type র‍্যামডিস্কের ধরণ NONE , PLATFORM , RECOVERY বা DLKM এর মধ্যে যেকোনো একটি হতে পারে।
--board_id[0-15] board_id ভেক্টরটি নির্দিষ্ট করুন, যার ডিফল্ট মান 0

নিচে একটি উদাহরণ কনফিগারেশন দেওয়া হলো:

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

ফলস্বরূপ vendor_boot দুটি ভেন্ডর র‍্যামডিস্ক ফ্র্যাগমেন্ট থাকবে। প্রথমটি হলো "ডিফল্ট" র‍্যামডিস্ক, যাতে DLKM ডিরেক্টরি baz এবং $(TARGET_VENDOR_RAMDISK_OUT) এর বাকি ফাইলগুলো থাকে। দ্বিতীয়টি হলো dlkm_foobar র‍্যামডিস্ক, যাতে DLKM ডিরেক্টরি foo এবং bar থাকে, এবং --ramdisk_type এর ডিফল্ট মান হলো DLKM