পার্টিশন লেআউট

অ্যান্ড্রয়েড ১০-এ, রুট ফাইল সিস্টেম আর ramdisk.img এর অন্তর্ভুক্ত থাকে না এবং এর পরিবর্তে এটি system.img এর সাথে একীভূত হয়ে যায় (অর্থাৎ, system.img সর্বদা এমনভাবে তৈরি হয় যেন BOARD_BUILD_SYSTEM_ROOT_IMAGE সেট করা ছিল)। অ্যান্ড্রয়েড ১০ সহ চালু হওয়া ডিভাইসগুলো:

  • সিস্টেম-কে-রুট পার্টিশন লেআউট ব্যবহার করুন (বিল্ড দ্বারা স্বয়ংক্রিয়ভাবে প্রয়োগ করা হয় এবং এই আচরণ পরিবর্তন করার কোনো বিকল্প নেই)।
  • অবশ্যই একটি র‍্যামডিস্ক ব্যবহার করতে হবে, যা ডিএম-লিনিয়ারের জন্য আবশ্যক।
  • BOARD_BUILD_SYSTEM_ROOT_IMAGE অবশ্যই false সেট করতে হবে। এই সেটিংটি শুধুমাত্র সেইসব ডিভাইসের মধ্যে পার্থক্য করার জন্য ব্যবহৃত হয় যেগুলো র‍্যামডিস্ক ব্যবহার করে এবং যেগুলো র‍্যামডিস্ক ব্যবহার করে না (এবং এর পরিবর্তে সরাসরি system.img মাউন্ট করে)।

অ্যান্ড্রয়েড ৯ এবং অ্যান্ড্রয়েড ১০-এর মধ্যে সিস্টেম-অ্যাজ-রুট কনফিগারেশনের অর্থ ভিন্ন। অ্যান্ড্রয়েড ৯-এর সিস্টেম-অ্যাজ-রুট কনফিগারেশনে, BOARD_BUILD_SYSTEM_ROOT_IMAGE ' true সেট করা থাকে, যা বিল্ডকে রুট ফাইল সিস্টেমকে system.img এর সাথে মার্জ করতে এবং তারপর system.img রুট ফাইল সিস্টেম (rootfs) হিসেবে মাউন্ট করতে বাধ্য করে। অ্যান্ড্রয়েড ৯ সহ লঞ্চ হওয়া ডিভাইসগুলির জন্য এই কনফিগারেশনটি বাধ্যতামূলক , কিন্তু অ্যান্ড্রয়েড ৯-এ আপগ্রেড করা ডিভাইস এবং অ্যান্ড্রয়েডের নিম্ন সংস্করণ চালিত ডিভাইসগুলির জন্য এটি ঐচ্ছিক । অ্যান্ড্রয়েড ১০-এর সিস্টেম-অ্যাজ-রুট কনফিগারেশনে, বিল্ড সর্বদা $TARGET_SYSTEM_OUT এবং $TARGET_ROOT_OUT system.img এর সাথে মার্জ করে; অ্যান্ড্রয়েড ১০ চালিত সমস্ত ডিভাইসের জন্য এই কনফিগারেশনটিই ডিফল্ট আচরণ।

অ্যান্ড্রয়েড ১০ ডাইনামিক পার্টিশন সমর্থন করার জন্য আরও কিছু পরিবর্তন এনেছে। এটি একটি ইউজারস্পেস পার্টিশনিং সিস্টেম যা ওভার-দ্য-এয়ার (OTA) আপডেটের মাধ্যমে পার্টিশন তৈরি, আকার পরিবর্তন বা ধ্বংস করতে সক্ষম করে। এই পরিবর্তনের অংশ হিসেবে, অ্যান্ড্রয়েড ১০ চালিত ডিভাইসগুলিতে লিনাক্স কার্নেল আর লজিক্যাল সিস্টেম পার্টিশন মাউন্ট করতে পারে না, তাই এই কাজটি প্রথম ধাপের ইনিট (init) দ্বারা পরিচালিত হয়।

নিম্নলিখিত বিভাগগুলিতে সিস্টেম-অনলি ওটিএ-এর জন্য সিস্টেম-অ্যাজ-রুট-এর প্রয়োজনীয়তা বর্ণনা করা হয়েছে এবং সিস্টেম-অ্যাজ-রুট ব্যবহার করার জন্য ডিভাইস আপডেট করার বিষয়ে নির্দেশনা দেওয়া হয়েছে (যার মধ্যে পার্টিশন লেআউট পরিবর্তন এবং dm-verity কার্নেলের প্রয়োজনীয়তা অন্তর্ভুক্ত)। র‍্যামডিস্কের পরিবর্তন সম্পর্কে বিস্তারিত জানতে, র‍্যামডিস্ক পার্টিশন দেখুন।

সিস্টেম-অনলি ওটিএ সম্পর্কে

সিস্টেম-অনলি ওটিএ, যা অন্যান্য পার্টিশন পরিবর্তন না করেই system.img এবং product.img ফাইল আপডেট করতে অ্যান্ড্রয়েড রিলিজকে সক্ষম করে, তার জন্য একটি সিস্টেম-অ্যাজ-রুট পার্টিশন লেআউট প্রয়োজন। সিস্টেম-অনলি ওটিএ চালু করার জন্য অ্যান্ড্রয়েড ১০ চালিত সমস্ত ডিভাইসে অবশ্যই একটি সিস্টেম-অ্যাজ-রুট পার্টিশন লেআউট ব্যবহার করতে হবে।

  • A/B ডিভাইস, যেগুলো system পার্টিশনকে রুটএফএস (rootfs) হিসেবে মাউন্ট করে, সেগুলো ইতিমধ্যেই সিস্টেম-অ্যাজ-রুট (system-as-root) ব্যবহার করে এবং সিস্টেম ওটিএ (OTA) সমর্থন করার জন্য সেগুলোতে কোনো পরিবর্তনের প্রয়োজন হয় না।
  • নন-এ/বি ডিভাইস, যেগুলো /systemsystem পার্টিশন মাউন্ট করে, সেগুলোকে সিস্টেম ওটিএ সমর্থন করার জন্য সিস্টেম-অ্যাজ-রুট পার্টিশন লেআউট ব্যবহার করতে আপডেট করতে হবে।

A/B এবং নন-A/B ডিভাইস সম্পর্কে বিস্তারিত জানতে, A/B (সিমলেস) সিস্টেম আপডেট দেখুন।

ভেন্ডর ওভারলে ব্যবহার করুন (<=AOSP 14)

ভেন্ডর ওভারলে আপনাকে ডিভাইস বুট করার সময় vendor পার্টিশনে পরিবর্তনগুলো স্থাপন করার সুযোগ দেয়। ভেন্ডর ওভারলে হলো product পার্টিশনে থাকা একগুচ্ছ ভেন্ডর মডিউল, যা ডিভাইস বুট করার সময় vendor পার্টিশনের উপর স্থাপিত হয় এবং বিদ্যমান মডিউলগুলোকে প্রতিস্থাপন ও সেগুলোর সাথে নতুন মডিউল যুক্ত করে।

যখন ডিভাইসটি বুট হয়, তখন init প্রসেসটি প্রথম ধাপের মাউন্ট সম্পন্ন করে এবং ডিফল্ট প্রোপার্টিগুলো পড়ে। এরপর এটি /product/vendor_overlay/<target_vendor_version> ডিরেক্টরিতে অনুসন্ধান করে এবং নিম্নলিখিত শর্তগুলো পূরণ হলে প্রতিটি সাবডিরেক্টরিকে তার সংশ্লিষ্ট vendor পার্টিশন ডিরেক্টরিতে মাউন্ট করে:

  • /vendor/<overlay_dir> বিদ্যমান।
  • /product/vendor_overlay/<target_vendor_version>/<overlay_dir> ফাইল কনটেক্সট /vendor/<overlay_dir> এর ফাইল কনটেক্সটের সমান।
  • init /vendor/<overlay_dir> এর ফাইল কনটেক্সটে মাউন্ট করার অনুমতি দেওয়া হয়েছে।

ভেন্ডর ওভারলে প্রয়োগ করুন

/product/vendor_overlay/<target_vendor_version> -এ ভেন্ডর ওভারলে ফাইলগুলি ইনস্টল করুন। ডিভাইস বুট করার সময় এই ফাইলগুলি vendor পার্টিশনের উপর একটি স্তর তৈরি করে, একই নামের ফাইলগুলিকে প্রতিস্থাপন করে এবং যেকোনো নতুন ফাইল যুক্ত করে। ভেন্ডর ওভারলে vendor পার্টিশন থেকে ফাইল সরাতে পারে না।

ভেন্ডর ওভারলে ফাইলগুলির ফাইল কনটেক্সট অবশ্যই vendor পার্টিশনে থাকা টার্গেট ফাইলগুলির ফাইল কনটেক্সটের সমান হতে হবে। ডিফল্টরূপে, /product/vendor_overlay/<target_vendor_version> ডিরেক্টরির ফাইলগুলির কনটেক্সট হলো vendor_file । যদি ভেন্ডর ওভারলে ফাইল এবং তাদের দ্বারা প্রতিস্থাপিত ফাইলগুলির মধ্যে ফাইল কনটেক্সটের অমিল থাকে, তবে ডিভাইস-নির্দিষ্ট sepolicy-তে তা উল্লেখ করুন। ফাইল কনটেক্সট ডিরেক্টরি লেভেলে সেট করা হয়। যদি কোনো ভেন্ডর ওভারলে ডিরেক্টরির ফাইল কনটেক্সট টার্গেট ডিরেক্টরির সাথে না মেলে, এবং ডিভাইস-নির্দিষ্ট sepolicy-তে সঠিক ফাইল কনটেক্সট উল্লেখ করা না থাকে, তবে সেই ভেন্ডর ওভারলে ডিরেক্টরিটি টার্গেট ডিরেক্টরির উপর ওভারলে করা হয় না।

ভেন্ডর ওভারলে ব্যবহার করার জন্য, কার্নেলকে অবশ্যই CONFIG_OVERLAY_FS=y সেট করে OverlayFS সক্রিয় করতে হবে। এছাড়াও, কার্নেলটিকে অবশ্যই কমন কার্নেল ৪.৪ বা তার পরবর্তী সংস্করণ থেকে মার্জ করা হতে হবে, অথবা "overlayfs: override_creds=off option bypass creator_cred" দিয়ে প্যাচ করা থাকতে হবে।

ভেন্ডর ওভারলে বাস্তবায়নের উদাহরণ

এই কার্যপ্রণালীতে একটি ভেন্ডর ওভারলে প্রয়োগ করার পদ্ধতি দেখানো হয়েছে, যা /vendor/lib/* , /vendor/etc/* , এবং /vendor/app/* ডিরেক্টরিগুলোকে আবৃত করে।

  1. device/<vendor>/<target>/vendor_overlay/<target_vendor_version>/ -এ আগে থেকে তৈরি ভেন্ডর ফাইল যোগ করুন:

    device/google/device/vendor_overlay/28/lib/libfoo.so
    device/google/device/vendor_overlay/28/lib/libbar.so
    device/google/device/vendor_overlay/28/etc/baz.xml
    device/google/device/vendor_overlay/28/app/qux.apk
  2. device/google/device/device.mk এর product/vendor_overlay তে আগে থেকে তৈরি ভেন্ডর ফাইলগুলি ইনস্টল করুন:

    PRODUCT_COPY_FILES += \
        $(call find-copy-subdir-files,*,device/google/device/vendor_overlay,$(TARGET_COPY_OUT_PRODUCT)/vendor_overlay)
  3. টার্গেট vendor পার্টিশন ফাইলগুলোর কনটেক্সট যদি vendor_file ছাড়া অন্য কিছু হয়, তাহলে ফাইল কনটেক্সটগুলো সংজ্ঞায়িত করুন। যেহেতু /vendor/lib/* ডিরেক্টরিটি vendor_file কনটেক্সট ব্যবহার করে, তাই এই উদাহরণে সেই ডিরেক্টরিটি অন্তর্ভুক্ত করা হয়নি।

    device/google/device-sepolicy/private/file_contexts এ নিম্নলিখিতটি যোগ করুন:

    /(product|system/product)/vendor_overlay/[0-9]+/etc(/.*)?   u:object_r:vendor_configs_file:s0
    /(product|system/product)/vendor_overlay/[0-9]+/app(/.*)?   u:object_r:vendor_app_file:s0
  4. init প্রসেসকে vendor_file ছাড়া অন্য ফাইল কনটেক্সটে ভেন্ডর ওভারলে মাউন্ট করার অনুমতি দিন। যেহেতু init প্রসেসের কাছে ইতিমধ্যেই vendor_file কনটেক্সটে মাউন্ট করার অনুমতি আছে, তাই এই উদাহরণে vendor_file জন্য পলিসি নির্ধারণ করা হয়নি।

    device/google/device-sepolicy/public/init.te তে নিম্নলিখিতটি যোগ করুন:

    allow init vendor_configs_file:dir mounton;
    allow init vendor_app_file:dir mounton;

বিক্রেতার ওভারলে যাচাই করুন

ভেন্ডর ওভারলে কনফিগারেশন যাচাই করতে, /product/vendor_overlay/<target_vendor_version>/<overlay_dir> এ ফাইল যোগ করুন এবং পরীক্ষা করে দেখুন যে ফাইলগুলি /vendor/<overlay_dir> এর ফাইলগুলির উপর ওভারলে করা হয়েছে কিনা।

userdebug বিল্ডের জন্য, Atest- এর একটি টেস্ট মডিউল রয়েছে:

$ atest -v fs_mgr_vendor_overlay_test

সিস্টেম-অ্যাজ-রুট হিসেবে আপডেট করুন

নন-এ/বি ডিভাইসগুলোকে সিস্টেম-অ্যাজ-রুট হিসেবে ব্যবহার করার জন্য আপডেট করতে হলে, আপনাকে অবশ্যই boot.imgsystem.img এর জন্য পার্টিশনিং স্কিম আপডেট করতে হবে, dm-verity সেট আপ করতে হবে এবং ডিভাইস-নির্দিষ্ট রুট ফোল্ডারগুলো থেকে যেকোনো বুট ডিপেন্ডেন্সি মুছে ফেলতে হবে।

পার্টিশন আপডেট করুন

A/B ডিভাইসগুলো যেখানে /boot পার্টিশনকে রিকভারি পার্টিশন হিসেবে ব্যবহার করে, তার থেকে ভিন্নভাবে, নন-A/B ডিভাইসগুলোতে /recovery পার্টিশনকে অবশ্যই আলাদা রাখতে হয়, কারণ সেগুলোতে ফলব্যাক স্লট পার্টিশন (যেমন, boot_a থেকে boot_b ) থাকে না। যদি কোনো নন-A/B ডিভাইস থেকে /recovery পার্টিশনটি সরিয়ে দিয়ে এটিকে A/B পদ্ধতির মতো করে তৈরি করা হয়, তাহলে /boot পার্টিশনের কোনো আপডেট ব্যর্থ হলে রিকভারি মোড অকার্যকর হয়ে যেতে পারে। এই কারণে, নন-A/B ডিভাইসগুলোর জন্য /recovery পার্টিশনটি অবশ্যই /boot থেকে একটি আলাদা পার্টিশন হতে হবে, যার অর্থ হলো রিকভারি ইমেজটি একটি বিলম্বিত পদ্ধতিতে আপডেট হতে থাকে (অর্থাৎ, অ্যান্ড্রয়েড ৮.১.০ বা তার নিচের সংস্করণে চালিত ডিভাইসগুলোর মতোই)।

নিম্নলিখিত সারণিতে অ্যান্ড্রয়েড ৯-এর আগে ও পরে নন-এ/বি ডিভাইসগুলোর ইমেজ পার্টিশনের পার্থক্যগুলো তালিকাভুক্ত করা হলো।

ছবি র‍্যামডিস্ক (অ্যান্ড্রয়েড ৯-এর আগে) সিস্টেম-রুট হিসেবে (অ্যান্ড্রয়েড ৯ এর পরে)
boot.img এতে একটি কার্নেল এবং একটি ramdisk.img রয়েছে:
ramdisk.img
  -/
    - init.rc
    - init
    - etc -> /system/etc
    - system/ (mount point)
    - vendor/ (mount point)
    - odm/ (mount point)
    ...
এতে শুধুমাত্র একটি সাধারণ বুট কার্নেল রয়েছে।
recovery.img এতে একটি রিকভারি কার্নেল এবং একটি রিকভারি ramdisk.img রয়েছে।
system.img নিম্নলিখিত বিষয়গুলো রয়েছে:
system.img
  -/
    - bin/
    - etc
    - vendor -> /vendor
    - ...
মূল system.img এবং ramdisk.img এর একত্রিত বিষয়বস্তু ধারণ করে:
system.img
  -/
    - init.rc
    - init
    - etc -> /system/etc
    - system/
      - bin/
      - etc/
      - vendor -> /vendor
      - ...
    - vendor/ (mount point)
    - odm/ (mount point)
    ...

পার্টিশনগুলো নিজেরা পরিবর্তিত হয় না; র‍্যামডিস্ক এবং সিস্টেম-অ্যাজ-রুট উভয়ই নিম্নলিখিত পার্টিশন স্কিম ব্যবহার করে:

  • /boot
  • /system
  • /system
  • /recovery
  • /vendor , ইত্যাদি।

dm-verity সেট আপ করুন

সিস্টেম-অ্যাজ-রুট অবস্থায়, কার্নেলকে অবশ্যই dm-verity ব্যবহার করে / (মাউন্ট পয়েন্ট)-এর অধীনে system.img মাউন্ট করতে হবে। AOSP, system.img এর জন্য নিম্নলিখিত dm-verity ইমপ্লিমেন্টেশনগুলো সমর্থন করে।

vboot 1.0

vboot 1.0- এর জন্য, কার্নেলকে অবশ্যই /system এ থাকা অ্যান্ড্রয়েড-নির্দিষ্ট মেটাডেটা পার্স করতে হবে, তারপর dm-verity সেট আপ করার জন্য সেটিকে dm-verity প্যারামিটারে রূপান্তর করতে হবে (এর জন্য এই কার্নেল প্যাচগুলো প্রয়োজন)। নিম্নলিখিত উদাহরণটি কার্নেল কমান্ড লাইনে system-as-root-এর জন্য dm-verity সম্পর্কিত সেটিংস দেখাচ্ছে:

ro root=/dev/dm-0 rootwait skip_initramfs init=/init
dm="system none ro,0 1 android-verity /dev/sda34"
veritykeyid=id:7e4333f9bba00adfe0ede979e28ed1920492b40f

vboot 2.0

vboot 2.0 ( AVB )-এর ক্ষেত্রে, বুটলোডারকে অবশ্যই external/avb/libavb সংহত করতে হবে, যা পরবর্তীতে /system এর হ্যাশট্রি ডেসক্রিপ্টর পার্স করে, সেটিকে dm-verity প্যারামিটারে রূপান্তর করে এবং সবশেষে কার্নেল কমান্ড লাইনের মাধ্যমে প্যারামিটারগুলো কার্নেলে প্রেরণ করে। ( /system এর হ্যাশট্রি ডেসক্রিপ্টরগুলো /vbmeta তে অথবা সরাসরি /system এ থাকতে পারে।)

vboot 2.0 এর জন্য নিম্নলিখিত কার্নেল প্যাচগুলো প্রয়োজন:

নিম্নলিখিত উদাহরণটি কার্নেল কমান্ড লাইনে system-as-root-এর জন্য dm-verity সম্পর্কিত সেটিংস দেখায়:

ro root=/dev/dm-0 rootwait  skip_initramfs init=/init

dm="1 vroot none ro 1,0 5159992 verity 1
PARTUUID=00000016-0000-0000-0000-000000000000
PARTUUID=00000016-0000-0000-0000-000000000000 4096 4096 644999 644999
sha1 d80b4a8be3b58a8ab86fad1b498640892d4843a2
8d08feed2f55c418fb63447fec0d32b1b107e42c 10 restart_on_corruption
ignore_zero_blocks use_fec_from_device
PARTUUID=00000016-0000-0000-0000-000000000000 fec_roots 2 fec_blocks
650080 fec_start 650080"

ডিভাইস-নির্দিষ্ট রুট ফোল্ডার ব্যবহার করুন

সিস্টেম-অ্যাজ-রুট অবস্থায়, ডিভাইসে জেনেরিক সিস্টেম ইমেজ (GSI) ফ্ল্যাশ করার পর (এবং ভেন্ডর টেস্ট স্যুট টেস্টগুলো চালানোর আগে), BOARD_ROOT_EXTRA_FOLDERS দিয়ে যোগ করা ডিভাইস-নির্দিষ্ট যেকোনো রুট ফোল্ডার মুছে যায়, কারণ সম্পূর্ণ রুট ডিরেক্টরির বিষয়বস্তু সিস্টেম-অ্যাজ-রুট GSI দ্বারা প্রতিস্থাপিত হয়ে যায়। এই ফোল্ডারগুলো মুছে ফেলার কারণে ডিভাইসটি আনবুটেবল হয়ে যেতে পারে, যদি ডিভাইস-নির্দিষ্ট রুট ফোল্ডারগুলোর উপর কোনো নির্ভরতা থাকে (উদাহরণস্বরূপ, এগুলো মাউন্ট পয়েন্ট হিসেবে ব্যবহৃত হয়)।

এই সমস্যাটি এড়াতে, ডিভাইস-নির্দিষ্ট রুট ফোল্ডার যোগ করার জন্য BOARD_ROOT_EXTRA_FOLDERS ব্যবহার করবেন না। যদি আপনার ডিভাইস-নির্দিষ্ট মাউন্ট পয়েন্ট উল্লেখ করার প্রয়োজন হয়, তাহলে /mnt/vendor/<mount point> ব্যবহার করুন (যা এই চেঞ্জলিস্টগুলিতে যোগ করা হয়েছে)। এই ভেন্ডর-নির্দিষ্ট মাউন্ট পয়েন্টগুলি অতিরিক্ত সেটআপ ছাড়াই সরাসরি fstab ডিভাইস ট্রি (প্রথম-পর্যায়ের মাউন্টের জন্য) এবং /vendor/etc/fstab.{ro.hardware} ফাইল উভয় স্থানেই উল্লেখ করা যেতে পারে (কারণ fs_mgr স্বয়ংক্রিয়ভাবে এগুলি /mnt/vendor/* এর অধীনে তৈরি করে)।