چیدمان پارتیشن

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

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

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

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

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

درباره OTA فقط سیستم

«به‌روزرسانی‌های از راه دور فقط سیستم» که نسخه‌های پخش Android را بدون تغییر دادن پارتیشن‌های دیگر به‌روزرسانی می‌کنند system.img و product.img، به چیدمان پارتیشن سیستم به‌عنوان ریشه نیاز دارند. همه دستگاه‌هایی که Android 10 را اجرا می‌کنند باید از طرح‌بندی پارتیشن سیستم به‌عنوان ریشه برای فعال کردن «به‌روزرسانی‌های از راه دور» فقط سیستم استفاده کنند.

  • دستگاه‌های A/B که پارتیشن system را به‌عنوان rootfs سوار می‌کنند، ازقبل از system-as-root استفاده می‌کنند و برای پشتیبانی از OTAهای سیستم نیازی به تغییر ندارند.
  • دستگاه‌های غیر A/B که پارتیشن system را در /system سوار می‌کنند، باید به‌روزرسانی شوند تا از چیدمان پارتیشن system-as-root برای پشتیبانی از OTAهای سیستم استفاده کنند.

برای جزئیات مربوط به دستگاه‌های 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 مختص دستگاه مشخص نشده باشد، آن دایرکتوری رونهاد فروشنده روی دایرکتوری هدف رونهاد نمی‌شود.

برای استفاده از رونهاد فروشنده، هسته باید OverlayFS را با تنظیم CONFIG_OVERLAY_FS=y فعال کند. همچنین، هسته باید از هسته مشترک ۴.۴ یا بالاتر ادغام شده باشد، یا با "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. فایل‌های فروشنده ازپیش ساخته‌شده را در 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_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

به‌روزرسانی به system-as-root

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

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

برخلاف دستگاه‌های A/B که از /boot به‌عنوان پارتیشن بازیابی استفاده مجدد می‌کنند، دستگاه‌های غیر A/B باید پارتیشن /recovery را جدا نگه دارند زیرا پارتیشن جایگزین ندارند (برای مثال، از boot_a به boot_b). اگر /recovery در دستگاه غیر A/B برداشته شود و شبیه طرح A/B شود، ممکن است حالت بازیابی درطول به‌روزرسانی ناموفق پارتیشن /boot ازکار بیفتد. For this reason, the /recovery partition must be a separate partition from /boot for non-A/B devices, which implies that the recovery image continues to be updated in a deferred manner (that is, the same as in devices running Android 8.1.0 or lower).

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

تصویر Ramdisk (قبل‌از Android 9) سیستم به‌عنوان ریشه (پس‌از Android 9)
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.img را در / (نقطه اتصال) با dm-verity نصب کند. ‫AOSP از پیاده‌سازی‌های dm-verity زیر برای system.img پشتیبانی می‌کند.

vboot 1.0

برای vboot 1.0، هسته باید فراداده‌های ویژه Android را در /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

برای vboot 2.0 (AVB)، bootloader باید external/avb/libavb را ادغام کند، که سپس توصیف‌گر hashtree را برای /system تجزیه می‌کند، آن را به پارامترهای dm-verity تبدیل می‌کند، و درنهایت پارامترها را ازطریق خط فرمان هسته به هسته ارسال می‌کند. (توصیف‌گرهای 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) در دستگاه فلش شد (و قبل‌از اجرای آزمایش‌های مجموعه آزمایش فروشنده)، هرگونه پوشه ریشه مختص دستگاه که با BOARD_ROOT_EXTRA_FOLDERS اضافه شده است ازبین می‌رود زیرا کل محتوای دایرکتوری ریشه با system-as-root GSI جایگزین شده است. اگر وابستگی به پوشه‌های ریشه مختص دستگاه وجود داشته باشد (برای مثال، از آن‌ها به‌عنوان نقاط نصب استفاده شود)، برداشتن این پوشه‌ها ممکن است باعث شود دستگاه قابل‌راه‌اندازی نباشد.

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