طرح پارتیشن، طرح پارتیشن

در اندروید ۱۰، فایل سیستم ریشه دیگر در ramdisk.img قرار ندارد و در عوض در system.img ادغام شده است (یعنی system.img همیشه طوری ایجاد می‌شود که انگار BOARD_BUILD_SYSTEM_ROOT_IMAGE تنظیم شده است). دستگاه‌هایی که با اندروید ۱۰ راه‌اندازی می‌شوند:

  • از طرح پارتیشن‌بندی سیستم به عنوان ریشه استفاده کنید (که به طور خودکار توسط سیستم عامل اعمال می‌شود و هیچ گزینه‌ای برای تغییر رفتار آن وجود ندارد).
  • باید از ramdisk استفاده شود که برای dm-linear مورد نیاز است.
  • باید BOARD_BUILD_SYSTEM_ROOT_IMAGE روی false تنظیم کنید. این تنظیم فقط برای تمایز بین دستگاه‌هایی که از ramdisk استفاده می‌کنند و دستگاه‌هایی که از ramdisk استفاده نمی‌کنند (و در عوض system.img را مستقیماً mount می‌کنند) استفاده می‌شود.

معنای پیکربندی system-as-root بین اندروید ۹ و اندروید ۱۰ متفاوت است. در پیکربندی system-as-root اندروید ۹، مقدار BOARD_BUILD_SYSTEM_ROOT_IMAGE روی true تنظیم شده است که باعث می‌شود build سیستم فایل root را در system.img ادغام کند و سپس system.img را به عنوان سیستم فایل root (rootfs) mount کند. این پیکربندی برای دستگاه‌هایی که با اندروید ۹ راه‌اندازی می‌شوند اجباری است، اما برای دستگاه‌هایی که به اندروید ۹ ارتقا می‌یابند و دستگاه‌هایی که نسخه‌های پایین‌تر اندروید را اجرا می‌کنند، اختیاری است. در پیکربندی system-as-root اندروید ۱۰، build همیشه $TARGET_SYSTEM_OUT و $TARGET_ROOT_OUT را در system.img ادغام می‌کند؛ این پیکربندی رفتار پیش‌فرض برای همه دستگاه‌هایی است که اندروید ۱۰ را اجرا می‌کنند.

اندروید ۱۰ تغییرات بیشتری را برای پشتیبانی از پارتیشن‌های پویا ایجاد می‌کند، یک سیستم پارتیشن‌بندی فضای کاربری که به‌روزرسانی‌های بی‌سیم (OTA) را برای ایجاد، تغییر اندازه یا از بین بردن پارتیشن‌ها امکان‌پذیر می‌کند. به عنوان بخشی از این تغییر، هسته لینوکس دیگر نمی‌تواند پارتیشن سیستم منطقی را روی دستگاه‌هایی که اندروید ۱۰ را اجرا می‌کنند، نصب کند، بنابراین این عملیات توسط init مرحله اول انجام می‌شود.

بخش‌های زیر الزامات سیستم به عنوان ریشه برای OTA های فقط سیستمی را شرح می‌دهند و راهنمایی‌هایی در مورد به‌روزرسانی دستگاه‌ها برای استفاده از سیستم به عنوان ریشه (از جمله تغییرات طرح پارتیشن و الزامات هسته dm-verity) ارائه می‌دهند. برای جزئیات بیشتر در مورد تغییرات در ramdisk، به Ramdisk Partitions مراجعه کنید.

درباره OTA های مخصوص سیستم

OTA های فقط سیستمی که به نسخه‌های اندروید امکان به‌روزرسانی system.img و product.img را بدون تغییر سایر پارتیشن‌ها می‌دهند، به یک طرح پارتیشن system-as-root نیاز دارند. همه دستگاه‌هایی که اندروید ۱۰ را اجرا می‌کنند باید از طرح پارتیشن system-as-root برای فعال کردن OTA های فقط سیستمی استفاده کنند.

برای جزئیات مربوط به دستگاه‌های A/B و غیر A/B، به به‌روزرسانی‌های سیستم A/B (یکپارچه) مراجعه کنید.

استفاده از پوشش فروشنده (<=AOSP 14)

قابلیت Vendor overlay به شما این امکان را می‌دهد که تغییرات پارتیشن vendor را در زمان بوت دستگاه، overlay کنید. یک vendor overlay مجموعه‌ای از ماژول‌های vendor در پارتیشن product است که هنگام بوت شدن دستگاه، روی پارتیشن vendor قرار می‌گیرند و ماژول‌های موجود را جایگزین و اضافه می‌کنند.

وقتی دستگاه بوت می‌شود، فرآیند init مرحله اول mount را کامل می‌کند و ویژگی‌های پیش‌فرض را می‌خواند. سپس در صورت برآورده شدن شرایط زیر /product/vendor_overlay/<target_vendor_version> را جستجو کرده و هر زیرشاخه را در دایرکتوری پارتیشن vendor مربوطه‌اش mount می‌کند:

  • /vendor/<overlay_dir> ‎ وجود دارد.
  • /product/vendor_overlay/<target_vendor_version>/<overlay_dir> ‎ همان چارچوب فایلی /vendor/<overlay_dir> را دارد.
  • init مجاز است که روی چارچوب فایل /vendor/<overlay_dir> نصب شود.

پیاده‌سازی پوشش فروشنده

فایل‌های vendor overlay را در مسیر /product/vendor_overlay/<target_vendor_version> نصب کنید. این فایل‌ها هنگام بوت شدن دستگاه، پارتیشن vendor را پوشش می‌دهند، فایل‌های همنام را جایگزین می‌کنند و فایل‌های جدید را اضافه می‌کنند. Vendor overlay نمی‌تواند فایل‌ها را از پارتیشن vendor حذف کند.

فایل‌های همپوشانی فروشنده باید همان چارچوب فایلی را داشته باشند که فایل‌های هدفی که در پارتیشن vendor جایگزین می‌کنند، دارند. به طور پیش‌فرض، فایل‌های موجود در دایرکتوری /product/vendor_overlay/<target_vendor_version> دارای چارچوب vendor_file هستند. اگر عدم تطابق چارچوب فایلی بین فایل‌های همپوشانی فروشنده و فایل‌هایی که جایگزین می‌کنند وجود دارد، آن را در بخش مربوط به دستگاه مشخص کنید. چارچوب فایل در سطح دایرکتوری تنظیم می‌شود. اگر چارچوب فایل یک دایرکتوری همپوشانی فروشنده با دایرکتوری هدف مطابقت نداشته باشد و چارچوب فایل صحیح در بخش مربوط به دستگاه مشخص نشده باشد، آن دایرکتوری همپوشانی فروشنده روی دایرکتوری هدف قرار نمی‌گیرد.

برای استفاده از vendor overlay، هسته باید OverlayFS را با تنظیم CONFIG_OVERLAY_FS=y فعال کند. همچنین، هسته باید از هسته رایج ۴.۴ یا بالاتر ادغام شود، یا با "overlayfs: override_creds=off option bypass creator_cred" وصله شود.

مثال پیاده‌سازی پوشش فروشنده

این رویه پیاده‌سازی یک پوشش فروشنده را نشان می‌دهد که دایرکتوری‌های /vendor/lib/* ، /vendor/etc/* و /vendor/app/* را پوشش می‌دهد.

  1. فایل‌های از پیش ساخته شده vendor را در 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. فایل‌های فروشنده از پیش ساخته شده را در product/vendor_overlay در device/google/device/device.mk نصب کنید:

    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 overlay را روی زمینه‌های فایلی غیر از 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

به‌روزرسانی به سیستم به عنوان ریشه

برای به‌روزرسانی دستگاه‌های غیر A/B برای استفاده از system-as-root، باید طرح پارتیشن‌بندی boot.img و system.img را به‌روزرسانی کنید، dm-verity را تنظیم کنید و هرگونه وابستگی بوت را در پوشه‌های ریشه مخصوص دستگاه حذف کنید.

پارتیشن‌ها را به‌روزرسانی کنید

برخلاف دستگاه‌های A/B که از /boot به عنوان پارتیشن ریکاوری استفاده می‌کنند، دستگاه‌های غیر A/B باید پارتیشن /recovery را جداگانه نگه دارند زیرا پارتیشن اسلات جایگزین (مثلاً از boot_a به boot_b ) /recovery . اگر /recovery در دستگاه غیر A/B حذف شود و مشابه طرح A/B باشد، حالت ریکاوری می‌تواند در حین به‌روزرسانی ناموفق پارتیشن /boot از کار بیفتد. به همین دلیل، پارتیشن /recovery برای دستگاه‌های غیر A/B باید یک پارتیشن جداگانه از /boot باشد، که نشان می‌دهد تصویر ریکاوری همچنان به صورت معوق به‌روزرسانی می‌شود (یعنی مشابه دستگاه‌هایی که اندروید ۸.۱.۰ یا پایین‌تر دارند).

جدول زیر تفاوت‌های پارتیشن‌بندی تصویر را برای دستگاه‌های غیر A/B قبل و بعد از اندروید ۹ نشان می‌دهد.

تصویر رم‌دیسک (قبل از اندروید ۹) سیستم به عنوان روت (بعد از اندروید ۹)
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)
    ...

خود پارتیشن‌ها تغییر نمی‌کنند؛ هم ramdisk و هم system-as-root از طرح پارتیشن‌بندی زیر استفاده می‌کنند:

  • /boot
  • /system
  • /system
  • /recovery
  • /vendor و غیره

تنظیم dm-verity

در حالت system-as-root، هسته باید system.img تحت / (نقطه اتصال) با dm-verity مانت کند. AOSP از پیاده‌سازی‌های dm-verity زیر برای system.img پشتیبانی می‌کند.

وی بوت ۱.۰

برای vboot 1.0 ، هسته باید فراداده‌های مخصوص اندروید را در /system تجزیه کند، سپس آنها را به پارامترهای dm-verity تبدیل کند تا dm-verity تنظیم شود ( به این وصله‌های هسته نیاز دارد). مثال زیر تنظیمات مربوط به dm-verity را برای system-as-root در خط فرمان هسته نشان می‌دهد:

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 ( AVB )، بوت‌لودر باید external/avb/libavb را ادغام کند، که سپس توصیف‌گر hashtree برای /system را تجزیه می‌کند، آن را به dm-verity params تبدیل می‌کند، و در نهایت پارامترها را از طریق خط فرمان هسته به هسته منتقل می‌کند. (توصیف‌گرهای hashtree برای /system ممکن است در /vbmeta یا در خود /system باشند.)

vboot 2.0 به پچ‌های کرنل زیر نیاز دارد:

مثال زیر تنظیمات مربوط به dm-verity را برای system-as-root در خط فرمان هسته نشان می‌دهد:

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"

از پوشه‌های ریشه مخصوص دستگاه استفاده کنید

با system-as-root، پس از فلش شدن تصویر سیستم عمومی (GSI) روی دستگاه (و قبل از اجرای تست‌های Vendor Test Suite )، هر پوشه ریشه مخصوص دستگاه که با BOARD_ROOT_EXTRA_FOLDERS اضافه شده باشد، از بین می‌رود زیرا کل محتوای دایرکتوری ریشه توسط GSI system-as-root جایگزین شده است. حذف این پوشه‌ها ممکن است باعث شود دستگاه غیرقابل بوت شود، اگر وابستگی به پوشه‌های ریشه مخصوص دستگاه وجود داشته باشد (برای مثال، از آنها به عنوان نقاط اتصال استفاده شود).

برای جلوگیری از این مشکل، BOARD_ROOT_EXTRA_FOLDERS برای اضافه کردن پوشه‌های ریشه مخصوص دستگاه استفاده نکنید. اگر نیاز به مشخص کردن نقاط اتصال مخصوص دستگاه دارید، از /mnt/vendor/<mount point> (که در این لیست‌های تغییر اضافه شده است) استفاده کنید. این نقاط اتصال مخصوص فروشنده را می‌توان مستقیماً در درخت دستگاه fstab (برای اتصال مرحله اول) و فایل /vendor/etc/fstab.{ro.hardware} بدون تنظیمات اضافی مشخص کرد (زیرا fs_mgr آنها را به طور خودکار در /mnt/vendor/* ایجاد می‌کند).