গতিশীল পার্টিশন বাস্তবায়ন

লিনাক্স কার্নেলের dm-লিনিয়ার ডিভাইস-ম্যাপার মডিউল ব্যবহার করে ডায়নামিক পার্টিশন প্রয়োগ করা হয়। super পার্টিশনে super এর মধ্যে প্রতিটি ডায়নামিক পার্টিশনের নাম এবং ব্লক রেঞ্জ তালিকাভুক্ত মেটাডেটা রয়েছে। প্রথম-পর্যায়ের init সময়, এই মেটাডেটা পার্স করা হয় এবং যাচাই করা হয়, এবং ভার্চুয়াল ব্লক ডিভাইসগুলি প্রতিটি গতিশীল পার্টিশনের প্রতিনিধিত্ব করার জন্য তৈরি করা হয়।

একটি OTA প্রয়োগ করার সময়, গতিশীল পার্টিশনগুলি স্বয়ংক্রিয়ভাবে তৈরি, পুনরায় আকার দেওয়া বা প্রয়োজন অনুসারে মুছে ফেলা হয়। A/B ডিভাইসের জন্য, মেটাডেটার দুটি কপি রয়েছে এবং পরিবর্তনগুলি শুধুমাত্র লক্ষ্য স্লটের প্রতিনিধিত্বকারী অনুলিপিতে প্রয়োগ করা হয়।

যেহেতু ডাইনামিক পার্টিশন ইউজারস্পেসে প্রয়োগ করা হয়, বুটলোডারের জন্য প্রয়োজনীয় পার্টিশনগুলিকে গতিশীল করা যায় না। উদাহরণস্বরূপ, boot , dtbo , এবং vbmeta বুটলোডার দ্বারা পড়া হয় এবং তাই অবশ্যই শারীরিক পার্টিশন হিসাবে থাকতে হবে।

প্রতিটি ডাইনামিক পার্টিশন একটি আপডেট গ্রুপের অন্তর্গত হতে পারে। এই গ্রুপগুলি সেই গ্রুপের পার্টিশনগুলি ব্যবহার করতে পারে এমন সর্বাধিক স্থান সীমাবদ্ধ করে। উদাহরণস্বরূপ, system এবং vendor এমন একটি গোষ্ঠীর অন্তর্গত হতে পারে যা system এবং vendor মোট আকারকে সীমাবদ্ধ করে।

নতুন ডিভাইসে গতিশীল পার্টিশন প্রয়োগ করুন

এই বিভাগে Android 10 এবং উচ্চতর সংস্করণের সাথে লঞ্চ হওয়া নতুন ডিভাইসগুলিতে কীভাবে গতিশীল পার্টিশন প্রয়োগ করা যায় তার বিশদ বিবরণ রয়েছে৷ বিদ্যমান ডিভাইসগুলি আপডেট করতে, অ্যান্ড্রয়েড ডিভাইসগুলি আপগ্রেড করা দেখুন।

পার্টিশন পরিবর্তন

অ্যান্ড্রয়েড 10 এর সাথে চালু হওয়া ডিভাইসগুলির জন্য, super নামে একটি পার্টিশন তৈরি করুন। super পার্টিশন অভ্যন্তরীণভাবে A/B স্লট পরিচালনা করে, তাই A/B ডিভাইসগুলির জন্য আলাদা super_a এবং super_b পার্টিশনের প্রয়োজন হয় না। বুটলোডার দ্বারা ব্যবহৃত নয় এমন সমস্ত পঠনযোগ্য AOSP পার্টিশন অবশ্যই গতিশীল হতে হবে এবং অবশ্যই GUID পার্টিশন টেবিল (GPT) থেকে মুছে ফেলতে হবে। বিক্রেতা-নির্দিষ্ট পার্টিশনগুলি গতিশীল হতে হবে না এবং GPT-এ স্থাপন করা যেতে পারে।

super আকার অনুমান করতে, GPT থেকে মুছে ফেলা পার্টিশনের আকার যোগ করুন। A/B ডিভাইসের জন্য, এতে উভয় স্লটের আকার অন্তর্ভুক্ত করা উচিত। চিত্র 1 ডায়নামিক পার্টিশনে রূপান্তর করার আগে এবং পরে একটি উদাহরণ পার্টিশন টেবিল দেখায়।

পার্টিশন টেবিল লেআউট
চিত্র 1. গতিশীল পার্টিশনে রূপান্তর করার সময় নতুন শারীরিক পার্টিশন টেবিল বিন্যাস

সমর্থিত গতিশীল পার্টিশন হল:

  • সিস্টেম
  • বিক্রেতা
  • পণ্য
  • সিস্টেম Ext
  • ওডিএম

অ্যান্ড্রয়েড 10 এর সাথে চালু হওয়া ডিভাইসগুলির জন্য, কার্নেল কমান্ড লাইন বিকল্প androidboot.super_partition খালি থাকতে হবে যাতে sysprop ro.boot.super_partition কমান্ডটি খালি থাকে।

বিভাজন প্রান্তিককরণ

super পার্টিশন সঠিকভাবে সারিবদ্ধ না হলে ডিভাইস-ম্যাপার মডিউল কম দক্ষতার সাথে কাজ করতে পারে। super পার্টিশনটি ব্লক স্তর দ্বারা নির্ধারিত ন্যূনতম I/O অনুরোধের আকারের সাথে সারিবদ্ধ হওয়া আবশ্যক। ডিফল্টরূপে, বিল্ড সিস্টেম ( lpmake এর মাধ্যমে, যা super পার্টিশন ইমেজ তৈরি করে), অনুমান করে যে প্রতিটি গতিশীল পার্টিশনের জন্য একটি 1 MiB প্রান্তিককরণ যথেষ্ট। যাইহোক, বিক্রেতাদের নিশ্চিত করা উচিত যে super পার্টিশনটি সঠিকভাবে সারিবদ্ধ করা হয়েছে।

আপনি sysfs পরিদর্শন করে একটি ব্লক ডিভাইসের ন্যূনতম অনুরোধের আকার নির্ধারণ করতে পারেন। যেমন:

# ls -l /dev/block/by-name/super
lrwxrwxrwx 1 root root 16 1970-04-05 01:41 /dev/block/by-name/super -> /dev/block/sda17
# cat /sys/block/sda/queue/minimum_io_size
786432

আপনি একই পদ্ধতিতে super পার্টিশনের সারিবদ্ধকরণ যাচাই করতে পারেন:

# cat /sys/block/sda/sda17/alignment_offset

প্রান্তিককরণ অফসেট 0 হতে হবে।

ডিভাইস কনফিগারেশন পরিবর্তন

গতিশীল পার্টিশন সক্রিয় করতে, device.mk এ নিম্নলিখিত পতাকা যোগ করুন:

PRODUCT_USE_DYNAMIC_PARTITIONS := true

বোর্ড কনফিগারেশন পরিবর্তন

আপনাকে super পার্টিশনের আকার সেট করতে হবে:

BOARD_SUPER_PARTITION_SIZE := <size-in-bytes>

A/B ডিভাইসে, গতিশীল পার্টিশন চিত্রের মোট আকার super পার্টিশন আকারের অর্ধেকের বেশি হলে বিল্ড সিস্টেম একটি ত্রুটি ছুড়ে দেয়।

আপনি নিম্নরূপ গতিশীল পার্টিশনের তালিকা কনফিগার করতে পারেন। আপডেট গোষ্ঠীগুলি ব্যবহার করে ডিভাইসগুলির জন্য, BOARD_SUPER_PARTITION_GROUPS ভেরিয়েবলে গোষ্ঠীগুলিকে তালিকাভুক্ত করুন৷ প্রতিটি গ্রুপের নামের সাথে একটি BOARD_ group _SIZE এবং BOARD_ group _PARTITION_LIST ভেরিয়েবল থাকে। A/B ডিভাইসের জন্য, একটি গ্রুপের সর্বাধিক আকার শুধুমাত্র একটি স্লট কভার করা উচিত, কারণ গ্রুপের নামগুলি অভ্যন্তরীণভাবে স্লট-প্রত্যয়যুক্ত।

এখানে একটি উদাহরণ ডিভাইস যা সমস্ত পার্টিশনকে example_dynamic_partitions নামে একটি গ্রুপে রাখে:

BOARD_SUPER_PARTITION_GROUPS := example_dynamic_partitions
BOARD_EXAMPLE_DYNAMIC_PARTITIONS_SIZE := 6442450944
BOARD_EXAMPLE_DYNAMIC_PARTITIONS_PARTITION_LIST := system vendor product

এখানে একটি উদাহরণ ডিভাইস যা সিস্টেম এবং পণ্য পরিষেবাগুলিকে group_foo , এবং vendor , product এবং odm group_bar এ রাখে:

BOARD_SUPER_PARTITION_GROUPS := group_foo group_bar
BOARD_GROUP_FOO_SIZE := 4831838208
BOARD_GROUP_FOO_PARTITION_LIST := system product_services
BOARD_GROUP_BAR_SIZE := 1610612736
BOARD_GROUP_BAR_PARTITION_LIST := vendor product odm
  • ভার্চুয়াল A/B লঞ্চ ডিভাইসগুলির জন্য, সমস্ত গোষ্ঠীর সর্বাধিক আকারের যোগফল সর্বাধিক হতে হবে:
    BOARD_SUPER_PARTITION_SIZE - ওভারহেড
    ভার্চুয়াল A/B বাস্তবায়ন দেখুন।
  • A/B লঞ্চ ডিভাইসের জন্য, সমস্ত গ্রুপের সর্বাধিক মাপের সমষ্টি হতে হবে:
    BOARD_SUPER_PARTITION_SIZE / 2 - ওভারহেড
  • নন-A/B ডিভাইস এবং রেট্রোফিট A/B ডিভাইসগুলির জন্য, সমস্ত গ্রুপের সর্বাধিক মাপের সমষ্টি হতে হবে:
    BOARD_SUPER_PARTITION_SIZE - ওভারহেড
  • বিল্ড টাইমে, আপডেট গ্রুপে প্রতিটি পার্টিশনের ইমেজের মাপের সমষ্টি অবশ্যই গ্রুপের সর্বোচ্চ আকারের বেশি হবে না।
  • মেটাডেটা, সারিবদ্ধকরণ ইত্যাদির জন্য হিসাব করার জন্য গণনায় ওভারহেড প্রয়োজন। একটি যুক্তিসঙ্গত ওভারহেড হল 4 MiB, তবে আপনি ডিভাইসের প্রয়োজন অনুসারে একটি বড় ওভারহেড বেছে নিতে পারেন।

সাইজ ডাইনামিক পার্টিশন

ডায়নামিক পার্টিশনের আগে, পার্টিশনের মাপ অতিরিক্ত বরাদ্দ করা হয়েছিল যাতে ভবিষ্যতে আপডেটের জন্য যথেষ্ট জায়গা থাকে। প্রকৃত আকার যেমন আছে তেমন নেওয়া হয়েছিল এবং বেশিরভাগ পঠনযোগ্য পার্টিশনের ফাইল সিস্টেমে কিছু পরিমাণ ফাঁকা জায়গা ছিল। গতিশীল পার্টিশনে, সেই ফাঁকা স্থানটি ব্যবহারযোগ্য নয় এবং একটি OTA চলাকালীন পার্টিশন বৃদ্ধি করতে ব্যবহার করা যেতে পারে। পার্টিশনগুলি যাতে স্থান নষ্ট না করে এবং ন্যূনতম সম্ভাব্য আকারে বরাদ্দ করা হয় তা নিশ্চিত করা গুরুত্বপূর্ণ।

শুধুমাত্র পঠনযোগ্য ext4 চিত্রের জন্য, বিল্ড সিস্টেম স্বয়ংক্রিয়ভাবে ন্যূনতম আকার বরাদ্দ করে যদি কোনো হার্ডকোডেড পার্টিশনের আকার নির্দিষ্ট করা না থাকে। বিল্ড সিস্টেমটি ইমেজের সাথে ফিট করে যাতে ফাইল সিস্টেমে যতটা সম্ভব কম অব্যবহৃত স্থান থাকে। এটি নিশ্চিত করে যে ডিভাইসটি ওটিএর জন্য ব্যবহার করা যেতে পারে এমন স্থান নষ্ট করে না।

অতিরিক্তভাবে, ব্লক-লেভেল ডিডপ্লিকেশন সক্ষম করে ext4 চিত্রগুলিকে আরও সংকুচিত করা যেতে পারে। এটি সক্ষম করতে, নিম্নলিখিত কনফিগারেশন ব্যবহার করুন:

BOARD_EXT4_SHARE_DUP_BLOCKS := true

পার্টিশনের ন্যূনতম আকারের স্বয়ংক্রিয় বরাদ্দ অবাঞ্ছিত হলে, পার্টিশনের আকার নিয়ন্ত্রণ করার দুটি উপায় রয়েছে। আপনি BOARD_ partition IMAGE_PARTITION_RESERVED_SIZE সাথে ন্যূনতম পরিমাণ খালি স্থান নির্দিষ্ট করতে পারেন, অথবা আপনি একটি নির্দিষ্ট আকারে গতিশীল পার্টিশন জোর করতে BOARD_ partition IMAGE_PARTITION_SIZE নির্দিষ্ট করতে পারেন। প্রয়োজন না হলে এইগুলির কোনটিই সুপারিশ করা হয় না।

যেমন:

BOARD_PRODUCTIMAGE_PARTITION_RESERVED_SIZE := 52428800

এটি product.img এ ফাইল সিস্টেমকে 50 MiB অব্যবহৃত স্থান রাখতে বাধ্য করে।

রুট হিসাবে সিস্টেম পরিবর্তন

অ্যান্ড্রয়েড 10 এর সাথে লঞ্চ করা ডিভাইসগুলি অবশ্যই রুট হিসাবে সিস্টেম ব্যবহার করবে না।

ডায়নামিক পার্টিশন সহ ডিভাইসগুলি (সেটি ডাইনামিক পার্টিশনের সাথে চালু হোক বা রেট্রোফিট করা হোক না কেন) সিস্টেম-এ-রুট ব্যবহার করা উচিত নয়। লিনাক্স কার্নেল super পার্টিশনকে ব্যাখ্যা করতে পারে না এবং তাই system নিজেই মাউন্ট করতে পারে না। system এখন প্রথম পর্যায়ের init দ্বারা মাউন্ট করা হয়েছে, যা ramdisk-এ থাকে।

BOARD_BUILD_SYSTEM_ROOT_IMAGE সেট করবেন না। অ্যান্ড্রয়েড 10-এ, BOARD_BUILD_SYSTEM_ROOT_IMAGE পতাকাটি শুধুমাত্র কার্নেল দ্বারা বা ramdisk-এ প্রথম-পর্যায়ের init দ্বারা মাউন্ট করা হয়েছে কিনা তা পার্থক্য করতে ব্যবহৃত হয়।

BOARD_BUILD_SYSTEM_ROOT_IMAGE কে true সেট করা বিল্ড ত্রুটির কারণ হয় যখন PRODUCT_USE_DYNAMIC_PARTITIONStrue হয়৷

যখন BOARD_USES_RECOVERY_AS_BOOT সত্যে সেট করা হয়, তখন পুনরুদ্ধারের চিত্রটি boot.img হিসাবে তৈরি করা হয়, যার মধ্যে পুনরুদ্ধারের রামডিস্ক থাকে। পূর্বে, বুটলোডার কোন মোডে বুট করতে হবে তা নির্ধারণ করতে skip_initramfs কার্নেল কমান্ড লাইন প্যারামিটার ব্যবহার করত। অ্যান্ড্রয়েড 10 ডিভাইসের জন্য, বুটলোডার অবশ্যই কার্নেল কমান্ড-লাইনে skip_initramfs পাস করবে না। পরিবর্তে, পুনরুদ্ধার এড়াতে এবং স্বাভাবিক অ্যান্ড্রয়েড বুট করতে বুটলোডারের androidboot.force_normal_boot=1 পাস করা উচিত। অ্যান্ড্রয়েড 12 বা তার পরে চালু হওয়া ডিভাইসগুলিকে অবশ্যই androidboot.force_normal_boot=1 পাস করতে bootconfig ব্যবহার করতে হবে।

AVB কনফিগারেশন পরিবর্তন

অ্যান্ড্রয়েড ভেরিফাইড বুট 2.0 ব্যবহার করার সময়, ডিভাইসটি যদি চেইনড পার্টিশন বর্ণনাকারী ব্যবহার না করে, তাহলে কোনো পরিবর্তনের প্রয়োজন নেই। যদি চেইনযুক্ত পার্টিশন ব্যবহার করা হয়, এবং যাচাইকৃত পার্টিশনগুলির মধ্যে একটি গতিশীল হয়, তাহলে পরিবর্তনগুলি আবশ্যক।

এখানে একটি ডিভাইসের জন্য একটি উদাহরণ কনফিগারেশন রয়েছে যা system এবং vendor পার্টিশনের জন্য vbmeta চেইন করে।

BOARD_AVB_SYSTEM_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem
BOARD_AVB_SYSTEM_ALGORITHM := SHA256_RSA2048
BOARD_AVB_SYSTEM_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP)
BOARD_AVB_SYSTEM_ROLLBACK_INDEX_LOCATION := 1

BOARD_AVB_VENDOR_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem
BOARD_AVB_VENDOR_ALGORITHM := SHA256_RSA2048
BOARD_AVB_VENDOR_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP)
BOARD_AVB_VENDOR_ROLLBACK_INDEX_LOCATION := 1

এই কনফিগারেশনের মাধ্যমে, বুটলোডার system এবং vendor পার্টিশনের শেষে একটি vbmeta ফুটার খুঁজে পাওয়ার আশা করে। যেহেতু এই পার্টিশনগুলি আর বুটলোডারের কাছে দৃশ্যমান নয় (এগুলি super তে থাকে), দুটি পরিবর্তন প্রয়োজন।

  • ডিভাইসের পার্টিশন টেবিলে vbmeta_system এবং vbmeta_vendor পার্টিশন যোগ করুন। A/B ডিভাইসের জন্য, vbmeta_system_a , vbmeta_system_b , vbmeta_vendor_a , এবং vbmeta_vendor_b যোগ করুন। এই পার্টিশনগুলির মধ্যে এক বা একাধিক যোগ করা হলে, সেগুলি vbmeta পার্টিশনের সমান হওয়া উচিত।
  • VBMETA_ যোগ করে কনফিগারেশন ফ্ল্যাগগুলির পুনঃনামকরণ করুন এবং কোন পার্টিশনে চেইনিং প্রসারিত হবে তা নির্দিষ্ট করুন:
    BOARD_AVB_VBMETA_SYSTEM := system
    BOARD_AVB_VBMETA_SYSTEM_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem
    BOARD_AVB_VBMETA_SYSTEM_ALGORITHM := SHA256_RSA2048
    BOARD_AVB_VBMETA_SYSTEM_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP)
    BOARD_AVB_VBMETA_SYSTEM_ROLLBACK_INDEX_LOCATION := 1
    
    BOARD_AVB_VBMETA_VENDOR := vendor
    BOARD_AVB_VBMETA_VENDOR_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem
    BOARD_AVB_VBMETA_VENDOR_ALGORITHM := SHA256_RSA2048
    BOARD_AVB_VBMETA_VENDOR_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP)
    BOARD_AVB_VBMETA_VENDOR_ROLLBACK_INDEX_LOCATION := 1

একটি ডিভাইস একটি, উভয়, বা এই পার্টিশনগুলির একটিও ব্যবহার করতে পারে। লজিক্যাল পার্টিশনে চেইন করার সময়ই পরিবর্তন প্রয়োজন।

AVB বুটলোডার পরিবর্তন

যদি বুটলোডার libavb এম্বেড করে থাকে, তাহলে নিম্নলিখিত প্যাচগুলি অন্তর্ভুক্ত করুন:

শৃঙ্খলিত পার্টিশন ব্যবহার করলে, একটি অতিরিক্ত প্যাচ অন্তর্ভুক্ত করুন:

  • 49936b4c0109411fdd38bd4ba3a32a01c40439a9 — "libavb: পার্টিশনের শুরুতে vbmeta blobs সমর্থন করে।"

কার্নেল কমান্ড লাইন পরিবর্তন

কার্নেল কমান্ড লাইনে একটি নতুন প্যারামিটার, androidboot.boot_devices যোগ করতে হবে। এটি /dev/block/by-name symlinks সক্রিয় করতে init দ্বারা ব্যবহৃত হয়। এটি ueventd দ্বারা তৈরি অন্তর্নিহিত বাই-নেম সিমলিংকের ডিভাইস পাথ উপাদান হওয়া উচিত, অর্থাৎ, /dev/block/platform/ device-path /by-name/ partition-name । Android 12 বা তার পরবর্তী সংস্করণের সাথে লঞ্চ করা ডিভাইসগুলিকে androidboot.boot_devices কে init করার জন্য bootconfig ব্যবহার করতে হবে।

উদাহরণস্বরূপ, যদি সুপার পার্টিশন বাই-নাম সিমলিংক /dev/block/platform/ soc/100000.ufshc /by-name/super হয়, তাহলে আপনি BoardConfig.mk ফাইলে কমান্ড লাইন প্যারামিটারটি নিম্নরূপ যোগ করতে পারেন:

BOARD_KERNEL_CMDLINE += androidboot.boot_devices=soc/100000.ufshc
আপনি BoardConfig.mk ফাইলে bootconfig প্যারামিটার যোগ করতে পারেন:
BOARD_BOOTCONFIG += androidboot.boot_devices=soc/100000.ufshc

fstab পরিবর্তন

ডিভাইস ট্রি এবং ডিভাইস ট্রি ওভারলেতে fstab এন্ট্রি থাকা উচিত নয়। একটি fstab ফাইল ব্যবহার করুন যা ramdisk এর অংশ হবে।

লজিক্যাল পার্টিশনের জন্য fstab ফাইলে পরিবর্তন করা আবশ্যক:

  • fs_mgr পতাকা ক্ষেত্রের মধ্যে অবশ্যই logical পতাকা এবং Android 10-এ প্রবর্তিত first_stage_mount পতাকা অন্তর্ভুক্ত থাকতে হবে, যা নির্দেশ করে যে প্রথম পর্যায়ে একটি পার্টিশন মাউন্ট করা হবে।
  • একটি পার্টিশন fs_mgr পতাকা হিসাবে avb= vbmeta partition name উল্লেখ করতে পারে এবং তারপরে নির্দিষ্ট vbmeta পার্টিশনটি কোনো ডিভাইস মাউন্ট করার চেষ্টা করার আগে প্রথম পর্যায়ে init দ্বারা আরম্ভ করা হয়।
  • dev ক্ষেত্রটি অবশ্যই পার্টিশনের নাম হতে হবে।

নিম্নলিখিত fstab এন্ট্রিগুলি উপরোক্ত নিয়মগুলি অনুসরণ করে সিস্টেম, বিক্রেতা এবং পণ্যকে লজিক্যাল পার্টিশন হিসাবে সেট করে।

#<dev>  <mnt_point> <type>  <mnt_flags options> <fs_mgr_flags>
system   /system     ext4    ro,barrier=1        wait,slotselect,avb=vbmeta,logical,first_stage_mount
vendor   /vendor     ext4    ro,barrier=1        wait,slotselect,avb,logical,first_stage_mount
product  /product    ext4    ro,barrier=1        wait,slotselect,avb,logical,first_stage_mount

প্রথম পর্যায়ের রামডিস্কে fstab ফাইলটি অনুলিপি করুন।

SELinux পরিবর্তন

সুপার পার্টিশন ব্লক ডিভাইস অবশ্যই super_block_device লেবেল দিয়ে চিহ্নিত করা উচিত। উদাহরণস্বরূপ, যদি সুপার পার্টিশন বাই-নাম সিমলিংক /dev/block/platform/ soc/100000.ufshc /by-name/super হয়, তাহলে file_contexts এ নিম্নলিখিত লাইন যোগ করুন:

/dev/block/platform/soc/10000\.ufshc/by-name/super   u:object_r:super_block_device:s0

fastbootd

বুটলোডার (বা যেকোন নন-ইউজারস্পেস ফ্ল্যাশিং টুল) ডাইনামিক পার্টিশন বোঝে না, তাই এটি তাদের ফ্ল্যাশ করতে পারে না। এটি মোকাবেলা করার জন্য, ডিভাইসগুলিকে fastboot প্রোটোকলের একটি ব্যবহারকারী-স্পেস বাস্তবায়ন ব্যবহার করতে হবে, যাকে বলা হয় fastbootd।

কিভাবে fastbootd প্রয়োগ করতে হয় সে সম্পর্কে আরও তথ্যের জন্য, দেখুন ফাস্টবুটকে ইউজার স্পেসে সরানো

adb রিমাউন্ট

eng বা userdebug বিল্ড ব্যবহার করে ডেভেলপারদের জন্য, দ্রুত পুনরাবৃত্তির জন্য adb remount অত্যন্ত উপযোগী। ডায়নামিক পার্টিশনগুলি adb remount জন্য একটি সমস্যা তৈরি করে কারণ প্রতিটি ফাইল সিস্টেমের মধ্যে আর ফাঁকা জায়গা নেই। এটি মোকাবেলা করার জন্য, ডিভাইসগুলি ওভারলেফগুলি সক্ষম করতে পারে। যতক্ষণ পর্যন্ত সুপার পার্টিশনের মধ্যে ফাঁকা জায়গা থাকে, ততক্ষণ adb remount স্বয়ংক্রিয়ভাবে একটি অস্থায়ী গতিশীল পার্টিশন তৈরি করে এবং লেখার জন্য ওভারলেফ ব্যবহার করে। অস্থায়ী পার্টিশনটির নাম scratch , তাই অন্য পার্টিশনের জন্য এই নামটি ব্যবহার করবেন না।

কিভাবে overlayfs সক্ষম করতে হয় সে সম্পর্কে আরও তথ্যের জন্য, AOSP-এ overlayfs README দেখুন।

অ্যান্ড্রয়েড ডিভাইস আপগ্রেড করুন

আপনি যদি Android 10-এ একটি ডিভাইস আপগ্রেড করেন এবং OTA-তে গতিশীল পার্টিশন সমর্থন অন্তর্ভুক্ত করতে চান, তাহলে আপনাকে বিল্ট-ইন পার্টিশন টেবিল পরিবর্তন করতে হবে না। কিছু অতিরিক্ত কনফিগারেশন প্রয়োজন.

ডিভাইস কনফিগারেশন পরিবর্তন

গতিশীল পার্টিশনের পুনরুদ্ধার করতে, device.mk এ নিম্নলিখিত ফ্ল্যাগগুলি যুক্ত করুন:

PRODUCT_USE_DYNAMIC_PARTITIONS := true
PRODUCT_RETROFIT_DYNAMIC_PARTITIONS := true

বোর্ড কনফিগারেশন পরিবর্তন

আপনাকে নিম্নলিখিত বোর্ড ভেরিয়েবল সেট করতে হবে:

  • BOARD_SUPER_PARTITION_BLOCK_DEVICES ব্লক ডিভাইসের তালিকায় সেট করুন যা ডায়নামিক পার্টিশনের পরিমাণ সঞ্চয় করতে ব্যবহৃত হয়। এটি ডিভাইসে বিদ্যমান শারীরিক পার্টিশনের নামের তালিকা।
  • যথাক্রমে BOARD_SUPER_PARTITION_BLOCK_DEVICES এ প্রতিটি ব্লক ডিভাইসের আকারে BOARD_SUPER_PARTITION_ partition _DEVICE_SIZE সেট করুন। এটি ডিভাইসে বিদ্যমান শারীরিক পার্টিশনের আকারের তালিকা। বিদ্যমান বোর্ড কনফিগারেশনে এটি সাধারণত BOARD_ partition IMAGE_PARTITION_SIZE
  • BOARD_SUPER_PARTITION_BLOCK_DEVICES এ সমস্ত পার্টিশনের জন্য বিদ্যমান BOARD_ partition IMAGE_PARTITION_SIZE আনসেট করুন।
  • BOARD_SUPER_PARTITION_SIZE BOARD_SUPER_PARTITION_ partition _DEVICE_SIZE এ সেট করুন।
  • BOARD_SUPER_PARTITION_METADATA_DEVICE ব্লক ডিভাইসে সেট করুন যেখানে ডায়নামিক পার্টিশন মেটাডেটা সংরক্ষণ করা হয়। এটি অবশ্যই BOARD_SUPER_PARTITION_BLOCK_DEVICES এর মধ্যে একটি হতে হবে। সাধারণত, এটি system সেট করা হয়।
  • যথাক্রমে BOARD_SUPER_PARTITION_GROUPS , BOARD_ group _SIZE এবং BOARD_ group _PARTITION_LIST সেট করুন। বিস্তারিত জানার জন্য নতুন ডিভাইসে বোর্ড কনফিগারেশন পরিবর্তন দেখুন।

উদাহরণস্বরূপ, যদি ডিভাইসটিতে ইতিমধ্যে সিস্টেম এবং ভেন্ডর পার্টিশন থাকে এবং আপনি সেগুলিকে গতিশীল পার্টিশনে রূপান্তর করতে চান এবং আপডেটের সময় একটি নতুন পণ্য পার্টিশন যোগ করতে চান, এই বোর্ড কনফিগারেশন সেট করুন:

BOARD_SUPER_PARTITION_BLOCK_DEVICES := system vendor
BOARD_SUPER_PARTITION_METADATA_DEVICE := system

# Rename BOARD_SYSTEMIMAGE_PARTITION_SIZE to BOARD_SUPER_PARTITION_SYSTEM_DEVICE_SIZE.
BOARD_SUPER_PARTITION_SYSTEM_DEVICE_SIZE := <size-in-bytes>

# Rename BOARD_VENDORIMAGE_PARTITION_SIZE to BOARD_SUPER_PARTITION_VENDOR_DEVICE_SIZE
BOARD_SUPER_PARTITION_VENDOR_DEVICE_SIZE := <size-in-bytes>

# This is BOARD_SUPER_PARTITION_SYSTEM_DEVICE_SIZE + BOARD_SUPER_PARTITION_VENDOR_DEVICE_SIZE
BOARD_SUPER_PARTITION_SIZE := <size-in-bytes>

# Configuration for dynamic partitions. For example:
BOARD_SUPER_PARTITION_GROUPS := group_foo
BOARD_GROUP_FOO_SIZE := <size-in-bytes>
BOARD_GROUP_FOO_PARTITION_LIST := system vendor product

SELinux পরিবর্তন

সুপার পার্টিশন ব্লক ডিভাইসগুলিকে super_block_device_type এট্রিবিউট দিয়ে চিহ্নিত করা আবশ্যক। উদাহরণস্বরূপ, যদি ডিভাইসে ইতিমধ্যেই system এবং vendor পার্টিশন থাকে, আপনি ডায়নামিক পার্টিশনের পরিমাণ সঞ্চয় করার জন্য সেগুলিকে ব্লক ডিভাইস হিসাবে ব্যবহার করতে চান এবং তাদের নামের সিমলিংকগুলিকে system_block_device হিসাবে চিহ্নিত করা হয়েছে :

/dev/block/platform/soc/10000\.ufshc/by-name/system   u:object_r:system_block_device:s0
/dev/block/platform/soc/10000\.ufshc/by-name/vendor   u:object_r:system_block_device:s0

তারপর, device.te এ নিম্নলিখিত লাইনটি যুক্ত করুন:

typeattribute system_block_device super_block_device_type;

অন্যান্য কনফিগারেশনের জন্য, নতুন ডিভাইসে গতিশীল পার্টিশন প্রয়োগ করা দেখুন।

রেট্রোফিট আপডেট সম্পর্কে আরও তথ্যের জন্য, ডায়নামিক পার্টিশন ছাড়া A/B ডিভাইসের জন্য OTA দেখুন।

কারখানার ছবি

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

এর সমাধানের জন্য, make dist এখন একটি অতিরিক্ত super.img ইমেজ তৈরি করে যা সরাসরি সুপার পার্টিশনে ফ্ল্যাশ করা যায়। এটি স্বয়ংক্রিয়ভাবে লজিক্যাল পার্টিশনের বিষয়বস্তুগুলিকে বান্ডেল করে, যার অর্থ এতে super পার্টিশন মেটাডেটা ছাড়াও system.img , vendor.img , এবং আরও অনেক কিছু রয়েছে৷ এই ছবিটি কোনো অতিরিক্ত টুলিং বা fastbootd ব্যবহার না করে সরাসরি super পার্টিশনে ফ্ল্যাশ করা যেতে পারে। বিল্ড করার পরে, super.img ${ANDROID_PRODUCT_OUT} এ স্থাপন করা হয়।

A/B ডিভাইসগুলির জন্য যেগুলি গতিশীল পার্টিশনের সাথে চালু হয়, super.img A স্লটে ছবি থাকে। সুপার ইমেজ সরাসরি ফ্ল্যাশ করার পরে, ডিভাইসটি রিবুট করার আগে স্লট A বুটযোগ্য হিসাবে চিহ্নিত করুন।

রেট্রোফিট ডিভাইসের জন্য, make dist super_*.img ইমেজের একটি সেট তৈরি করে যা সরাসরি সংশ্লিষ্ট ফিজিক্যাল পার্টিশনে ফ্ল্যাশ করা যায়। উদাহরণস্বরূপ, যখন BOARD_SUPER_PARTITION_BLOCK_DEVICES সিস্টেম বিক্রেতা হয় তখন make dist builds super_system.img এবং super_vendor.img তৈরি করুন। এই ছবিগুলি target_files.zip এ OTA ফোল্ডারে রাখা হয়েছে।

ডিভাইস ম্যাপার স্টোরেজ-ডিভাইস টিউনিং

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

init ভিতরের একটি প্রক্রিয়া মাউন্টগুলিকে ট্র্যাক করে এবং অ্যাসিঙ্ক্রোনাসভাবে Android বৈশিষ্ট্যগুলিকে আপডেট করে। এটি যে পরিমাণ সময় নেয় তা একটি নির্দিষ্ট সময়ের মধ্যে হওয়ার গ্যারান্টি দেওয়া হয় না, তাই আপনাকে অবশ্যই on property ট্রিগারগুলিতে প্রতিক্রিয়া জানানোর জন্য পর্যাপ্ত সময় দিতে হবে। বৈশিষ্ট্যগুলি হল dev.mnt.blk. <partition> যেখানে <partition> হল root , system , data বা vendor , উদাহরণস্বরূপ। প্রতিটি সম্পত্তি বেস স্টোরেজ-ডিভাইস নামের সাথে যুক্ত, যেমন এই উদাহরণগুলিতে দেখানো হয়েছে:

taimen:/ % getprop | grep dev.mnt.blk
[dev.mnt.blk.data]: [sda]
[dev.mnt.blk.firmware]: [sde]
[dev.mnt.blk.metadata]: [sde]
[dev.mnt.blk.persist]: [sda]
[dev.mnt.blk.root]: [dm-0]
[dev.mnt.blk.vendor]: [dm-1]

blueline:/ $ getprop | grep dev.mnt.blk
[dev.mnt.blk.data]: [dm-4]
[dev.mnt.blk.metadata]: [sda]
[dev.mnt.blk.mnt.scratch]: [sda]
[dev.mnt.blk.mnt.vendor.persist]: [sdf]
[dev.mnt.blk.product]: [dm-2]
[dev.mnt.blk.root]: [dm-0]
[dev.mnt.blk.system_ext]: [dm-3]
[dev.mnt.blk.vendor]: [dm-1]
[dev.mnt.blk.vendor.firmware_mnt]: [sda]

init.rc ভাষা নিয়মের অংশ হিসাবে অ্যান্ড্রয়েড বৈশিষ্ট্যগুলিকে প্রসারিত করার অনুমতি দেয় এবং স্টোরেজ ডিভাইসগুলিকে প্ল্যাটফর্মের দ্বারা এই ধরনের কমান্ডের সাথে প্রয়োজন অনুসারে টিউন করা যেতে পারে:

write /sys/block/${dev.mnt.blk.root}/queue/read_ahead_kb 128
write /sys/block/${dev.mnt.blk.data}/queue/read_ahead_kb 128

দ্বিতীয় পর্যায়ের init এ কমান্ড প্রসেসিং শুরু হলে, epoll loop সক্রিয় হয়, এবং মানগুলি আপডেট হতে শুরু করে। যাইহোক, যেহেতু প্রপার্টি ট্রিগারগুলি দেরী- init পর্যন্ত সক্রিয় থাকে না, তাই root , system বা vendor পরিচালনা করতে প্রাথমিক বুট পর্যায়ে ব্যবহার করা যাবে না। init.rc স্ক্রিপ্ট early-fs (যখন বিভিন্ন ডেমন এবং সুবিধা শুরু হয়) ওভাররাইড না করা পর্যন্ত আপনি কার্নেল ডিফল্ট read_ahead_kb যথেষ্ট হবে বলে আশা করতে পারেন। তাই, Google সুপারিশ করে যে আপনি একটি init.rc -নিয়ন্ত্রিত প্রপার্টি যেমন sys.read_ahead_kb সাথে মিলিত on property বৈশিষ্ট্যটি ব্যবহার করুন, ক্রিয়াকলাপগুলির সময়কে মোকাবেলা করতে এবং জাতি পরিস্থিতি প্রতিরোধ করতে, এই উদাহরণগুলির মতো:

on property:dev.mnt.blk.root=* && property:sys.read_ahead_kb=*
    write /sys/block/${dev.mnt.blk.root}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048}

on property:dev.mnt.blk.system=* && property:sys.read_ahead_kb=*
    write /sys/block/${dev.mnt.blk.system}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048}

on property:dev.mnt.blk.vendor=* && property:sys.read_ahead_kb=*
    write /sys/block/${dev.mnt.blk.vendor}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048}

on property:dev.mnt.blk.product=* && property:sys.read_ahead_kb=*
    write /sys/block/${dev.mnt.blk.system_ext}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048}

on property:dev.mnt.blk.oem=* && property:sys.read_ahead_kb=*
    write /sys/block/${dev.mnt.blk.oem}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048}

on property:dev.mnt.blk.data=* && property:sys.read_ahead_kb=*
    write /sys/block/${dev.mnt.blk.data}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048}

on early-fs:
    setprop sys.read_ahead_kb ${ro.read_ahead_kb.boot:-2048}

on property:sys.boot_completed=1
   setprop sys.read_ahead_kb ${ro.read_ahead_kb.bootcomplete:-128}