يتم تنفيذ التقسيم الديناميكي باستخدام وحدة dm-linear الخاصة ببرنامج device-mapper في نواة Linux. يحتوي القسم super
على بيانات وصفية تسرد أسماء ونطاقات الحظر لكل قسم ديناميكي ضمن super
. أثناء المرحلة الأولى init
، يتم تحليل هذه البيانات الوصفية والتحقّق من صحتها، ويتم إنشاء أجهزة تخزين بالكتل الافتراضية لتمثيل كل قسم ديناميكي.
عند تطبيق تحديث عبر الأثير (OTA)، يتم تلقائيًا إنشاء الأقسام الديناميكية أو تغيير حجمها أو حذفها حسب الحاجة. بالنسبة إلى الأجهزة التي تستخدم نظام التشغيل A/B، تتوفّر نسختان من البيانات الوصفية، ويتم تطبيق التغييرات على النسخة التي تمثّل الخانة المستهدَفة فقط.
بما أنّ الأقسام الديناميكية يتم تنفيذها في مساحة المستخدم، لا يمكن إنشاء أقسام ديناميكية يحتاج إليها برنامج التشغيل. على سبيل المثال، يقرأ برنامج الإقلاع boot
وdtbo
وvbmeta
، لذا يجب أن تظل هذه الأقسام مادية.
يمكن أن ينتمي كل قسم ديناميكي إلى مجموعة تحديث. تحدّد هذه المجموعات الحد الأقصى للمساحة التي يمكن أن تستهلكها الأقسام في تلك المجموعة.
على سبيل المثال، يمكن أن ينتمي system
وvendor
إلى مجموعة تفرض قيودًا على الحجم الإجمالي لكل من system
وvendor
.
تنفيذ الأقسام الديناميكية على الأجهزة الجديدة
يوضّح هذا القسم بالتفصيل كيفية تنفيذ الأقسام الديناميكية على الأجهزة الجديدة التي تعمل بالإصدار Android 10 والإصدارات الأحدث. لتحديث الأجهزة الحالية، يُرجى الاطّلاع على مقالة ترقية أجهزة Android.
تغييرات الأقسام
بالنسبة إلى الأجهزة التي تعمل بنظام التشغيل Android 10، أنشئ قسمًا باسم super
. يتعامل القسم super
مع خانات A/B داخليًا، لذا لا تحتاج أجهزة A/B إلى قسمَين منفصلَين super_a
وsuper_b
.
يجب أن تكون جميع أقسام AOSP للقراءة فقط وغير المستخدَمة من قِبل برنامج التشغيل قابلة للتغيير، ويجب إزالتها من جدول أقسام GUID.
لا يجب أن تكون الأقسام الخاصة بالمورّدين ديناميكية، ويمكن وضعها في GPT.
لتقدير حجم super
، أضِف أحجام الأقسام التي يتم حذفها من GPT. بالنسبة إلى الأجهزة التي تستخدم نظام التشغيل Android A/B، يجب أن يشمل ذلك حجم كلا الفتحتين. يعرض الشكل 1 مثالاً على جدول أقسام قبل وبعد التحويل إلى أقسام ديناميكية.

في ما يلي الأقسام الديناميكية المتوافقة:
- النظام
- المورّد
- المنتَج
- System Ext
- ODM
بالنسبة إلى الأجهزة التي تعمل بنظام التشغيل Android 10، يجب أن يكون خيار سطر أوامر kernel androidboot.super_partition
فارغًا حتى يكون الأمر sysprop ro.boot.super_partition
فارغًا.
محاذاة الأقسام
قد يعمل وحدة device-mapper بكفاءة أقل إذا لم تتم محاذاة القسم super
بشكل صحيح. يجب أن يكون قسم super
متوافقًا مع الحد الأدنى لحجم طلب الإدخال/الإخراج الذي تحدّده طبقة الحظر. بشكلٍ تلقائي، يفترض نظام الإنشاء (من خلال 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
تغييرات في إعدادات لوحة Jamboard
يجب تحديد حجم القسم super
:
BOARD_SUPER_PARTITION_SIZE := <size-in-bytes>
على أجهزة A/B، يعرض نظام الإنشاء خطأً إذا كان الحجم الإجمالي لصور الأقسام الديناميكية أكبر من نصف حجم القسم super
.
يمكنك ضبط قائمة الأقسام الديناميكية على النحو التالي. بالنسبة إلى الأجهزة التي تستخدم مجموعات التحديث، أدرِج المجموعات في المتغيّر BOARD_SUPER_PARTITION_GROUPS
. يحتوي كل اسم مجموعة
بعد ذلك على BOARD_group_SIZE
ومتغيّر BOARD_group_PARTITION_LIST
.
بالنسبة إلى الأجهزة التي تستخدم نظام التشغيل Android 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
-
بالنسبة إلى الأجهزة التي يتم إطلاقها باستخدام ميزة "اختبار أ/ب الافتراضي"، يجب أن يكون مجموع الحد الأقصى لأحجام جميع المجموعات
على النحو التالي:
BOARD_SUPER_PARTITION_SIZE
- النفقات العامة
راجِع تنفيذ ميزة "اختبار أ/ب الافتراضي". -
بالنسبة إلى الأجهزة التي يمكن إجراء اختبار الإطلاق عليها، يجب أن يكون مجموع الحد الأقصى لأحجام جميع المجموعات
كما يلي:
BOARD_SUPER_PARTITION_SIZE
/ 2 - النفقات العامة -
بالنسبة إلى الأجهزة غير المتوافقة مع نظام التشغيل A/B والأجهزة المتوافقة مع نظام التشغيل A/B التي تم تعديلها، يجب أن يكون مجموع الحد الأقصى لأحجام جميع المجموعات كما يلي:
BOARD_SUPER_PARTITION_SIZE
- النفقات العامة - في وقت الإنشاء، يجب ألا يتجاوز مجموع أحجام صور كل قسم في مجموعة التحديث الحد الأقصى لحجم المجموعة.
- النفقات العامة مطلوبة في عملية الحساب لتفسير البيانات الوصفية وعمليات المحاذاة وما إلى ذلك. يبلغ الحد المعقول للزيادة في الحجم 4 MiB، ولكن يمكنك اختيار زيادة أكبر في الحجم حسب ما يحتاج إليه الجهاز.
تقسيمات ديناميكية حسب الحجم
قبل الأقسام الديناميكية، كان يتم تخصيص أحجام الأقسام بشكل مفرط لضمان توفّر مساحة كافية للتحديثات المستقبلية. تم أخذ الحجم الفعلي كما هو، وكانت معظم الأقسام للقراءة فقط تتضمّن بعض المساحة الحرة في نظام الملفات. في الأقسام الديناميكية، تكون مساحة التخزين الحرة هذه غير قابلة للاستخدام ويمكن استخدامها لتوسيع الأقسام أثناء التحديث عبر الأثير. من الضروري التأكّد من أنّ الأقسام لا تستهلك مساحة كبيرة وأنّه تم تخصيصها بأقل حجم ممكن.
بالنسبة إلى صور ext4 للقراءة فقط، يخصّص نظام الإصدار تلقائيًا الحد الأدنى للحجم إذا لم يتم تحديد حجم ثابت للقسم. يعدّل نظام الإنشاء حجم الصورة بحيث يكون الحد الأدنى من المساحة غير المستخدَمة في نظام الملفات. ويضمن ذلك ألا يستهلك الجهاز مساحة يمكن استخدامها في تحديثات عبر الأثير.
بالإضافة إلى ذلك، يمكن ضغط صور ext4 بشكل أكبر من خلال تفعيل ميزة إزالة البيانات المكررة على مستوى الحظر. لتفعيل ذلك، استخدِم الإعداد التالي:
BOARD_EXT4_SHARE_DUP_BLOCKS := true
إذا كان التخصيص التلقائي للحد الأدنى لحجم القسم غير مرغوب فيه،
هناك طريقتان للتحكّم في حجم القسم. يمكنك تحديد الحد الأدنى لمقدار المساحة الحرة باستخدام BOARD_partitionIMAGE_PARTITION_RESERVED_SIZE
، أو يمكنك تحديد BOARD_partitionIMAGE_PARTITION_SIZE
لفرض حجم معيّن على الأقسام الديناميكية. ولا ننصح بأي من هذين الإجراءين إلا عند الضرورة.
مثلاً:
BOARD_PRODUCTIMAGE_PARTITION_RESERVED_SIZE := 52428800
يؤدي ذلك إلى فرض توفّر مساحة غير مستخدَمة تبلغ 50 ميغابايت في نظام الملفات في product.img
.
التغييرات على النظام كجذر
يجب ألا تستخدم الأجهزة التي تعمل بالإصدار 10 من نظام التشغيل Android نظام التشغيل كجذر.
يجب ألا تستخدم الأجهزة ذات الأقسام الديناميكية (سواء تم إطلاقها مع أقسام ديناميكية أو تم تعديلها لتشمل أقسامًا ديناميكية) نظام التشغيل كجذر. لا يمكن لنواة Linux تفسير القسم super
، وبالتالي لا يمكنها تحميل system
. يتم الآن تحميل system
بواسطة
init
في المرحلة الأولى، والذي يقع في ramdisk.
لا تضبط BOARD_BUILD_SYSTEM_ROOT_IMAGE
. في نظام التشغيل Android 10، لا يتم استخدام العلامة BOARD_BUILD_SYSTEM_ROOT_IMAGE
إلا للتمييز بين ما إذا كان النظام مثبّتًا بواسطة النواة أو بواسطة init
في المرحلة الأولى في ramdisk.
يؤدي ضبط BOARD_BUILD_SYSTEM_ROOT_IMAGE
على true
إلى حدوث خطأ في الإنشاء عندما تكون قيمة PRODUCT_USE_DYNAMIC_PARTITIONS
هي true
أيضًا.
عند ضبط BOARD_USES_RECOVERY_AS_BOOT
على "صحيح"، يتم إنشاء صورة الاسترداد كملف boot.img يحتوي على ملف ramdisk الخاص بالاسترداد. في السابق، كان برنامج Bootloader يستخدم مَعلمة سطر الأوامر skip_initramfs
الخاصة بالنواة لتحديد الوضع الذي سيتم التشغيل فيه. بالنسبة إلى أجهزة Android 10، يجب ألا يمرّر برنامج التشغيل skip_initramfs
إلى سطر أوامر النواة. بدلاً من ذلك، يجب أن يمرِّر برنامج التحميل androidboot.force_normal_boot=1
لتخطّي وضع الاسترداد وتشغيل نظام Android العادي. يجب أن تستخدم الأجهزة التي تعمل بالإصدار 12 من نظام التشغيل Android أو الإصدارات الأحدث bootconfig لتمرير androidboot.force_normal_boot=1
.
تغييرات في إعدادات AVB
عند استخدام التحقّق من صحة التشغيل 2.0 على Android، إذا كان الجهاز لا يستخدم واصفات الأقسام المتسلسلة، لن يكون من الضروري إجراء أي تغيير. في حال استخدام أقسام مرتبطة، وكان أحد الأقسام التي تم التحقّق منها ديناميكيًا، يجب إجراء تغييرات.
في ما يلي مثال على إعدادات جهاز يربط بين
vbmeta
لقسمَي system
وvendor
.
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
باستخدام هذا الإعداد، يتوقّع برنامج التحميل العثور على تذييل vbmetaفي نهاية القسمين system
وvendor
. وبما أنّ هذه الأقسام لم تعُد مرئية لبرنامج التحميل (لأنّها تقع في 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، يجب تضمين التصحيحات التالية:
- 818cf56740775446285466eda984acedd4baeac0 — "libavb: Only query partition GUIDs when the cmdline needs them."
- 5abd6bc2578968d24406d834471adfd995a0c2e9 — "السماح بعدم توفّر قسم النظام"
- 9ba3b6613b4e5130fa01a11d984c6b5f0eb3af05 — "Fix AvbSlotVerifyData->cmdline might be NULL"
في حال استخدام الأقسام المتسلسلة، أدرِج رمز تصحيح إضافيًا:
- 49936b4c0109411fdd38bd4ba3a32a01c40439a9 — "libavb: Support vbmeta blobs in beginning of partition."
التغييرات على سطر أوامر النواة
يجب إضافة مَعلمة جديدة، androidboot.boot_devices
، إلى سطر أوامر النواة. يتم استخدام هذا الخيار بواسطة init
لتفعيل الروابط الرمزية /dev/block/by-name
. يجب أن يكون مكوّن مسار الجهاز إلى الرابط الرمزي الأساسي الذي تم إنشاؤه بواسطة ueventd
، أي /dev/block/platform/device-path/by-name/partition-name
.
يجب أن تستخدم الأجهزة التي تعمل بالإصدار 12 من نظام التشغيل Android أو الإصدارات الأحدث bootconfig لتمرير androidboot.boot_devices
إلى init
.
على سبيل المثال، إذا كان الرابط الرمزي الخاص بالقسم الفائق حسب الاسم هو
/dev/block/platform/soc/100000.ufshc/by-name/super
،
يمكنك إضافة مَعلمة سطر الأوامر في ملف BoardConfig.mk على النحو التالي:
BOARD_KERNEL_CMDLINE += androidboot.boot_devices=soc/100000.ufshc
BOARD_BOOTCONFIG += androidboot.boot_devices=soc/100000.ufshc
تغييرات fstab
يجب ألا يحتوي كل من شجرة الأجهزة وتراكبات شجرة الأجهزة على إدخالات fstab. استخدِم ملف fstab الذي سيكون جزءًا من ramdisk.
يجب إجراء تغييرات على ملف fstab للأقسام المنطقية:
-
يجب أن يتضمّن حقل العلامات fs_mgr العلامة
logical
والعلامةfirst_stage_mount
التي تم طرحها في نظام التشغيل Android 10، وتشير إلى أنّه سيتم تثبيت أحد الأقسام في المرحلة الأولى. -
قد يحدّد القسم
avb=vbmeta partition name
كعلامةfs_mgr
، ثم يتم تهيئة القسم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 إلى ramdisk في المرحلة الأولى.
تغييرات SELinux
يجب وضع التصنيف super_block_device
على جهاز حظر التقسيم الفائق. على سبيل المثال، إذا كان رابط super partition by-name symlink هو
/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، يُرجى الاطّلاع على نقل Fastboot إلى مساحة المستخدم.
adb remount
بالنسبة إلى المطوّرين الذين يستخدمون إصدارات eng أو userdebug، يكون adb remount
مفيدًا للغاية للتكرار السريع. تسبّب الأقسام الديناميكية مشكلة في adb remount
لأنّه لم تعُد هناك مساحة حرة داخل كل نظام ملفات. لحلّ هذه المشكلة، يمكن للأجهزة تفعيل overlayfs. طالما توفّرت مساحة حرة ضمن القسم الفائق، ينشئ adb remount
تلقائيًا قسمًا ديناميكيًا مؤقتًا ويستخدم overlayfs لعمليات الكتابة. اسم القسم المؤقت هو scratch
، لذا لا تستخدِم هذا الاسم لأقسام أخرى.
لمزيد من المعلومات حول كيفية تفعيل overlayfs، يُرجى الاطّلاع على ملف overlayfs README في مشروع AOSP.
ترقية أجهزة Android
إذا تمت ترقية جهاز إلى Android 10 وأردت تضمين إمكانية استخدام الأقسام الديناميكية في التحديث عبر الأثير (OTA)، لن تحتاج إلى تغيير جدول الأقسام المضمّن. يجب إجراء بعض عمليات الضبط الإضافية.
تغييرات في إعدادات الجهاز
لإعادة تصميم التقسيم الديناميكي، أضِف العلامات التالية في
device.mk
:
PRODUCT_USE_DYNAMIC_PARTITIONS := true PRODUCT_RETROFIT_DYNAMIC_PARTITIONS := true
تغييرات في إعدادات لوحة Jamboard
يجب ضبط متغيّرات اللوحة التالية:
- اضبط
BOARD_SUPER_PARTITION_BLOCK_DEVICES
على قائمة أجهزة التخزين بالكتل المستخدَمة لتخزين مدى الأقسام الديناميكية. هذه هي قائمة بأسماء الأقسام الفعلية الحالية على الجهاز. - اضبط
BOARD_SUPER_PARTITION_partition_DEVICE_SIZE
على أحجام كل جهاز تخزين بالكتل فيBOARD_SUPER_PARTITION_BLOCK_DEVICES
، على التوالي. هذه هي قائمة بأحجام الأقسام الفعلية الحالية على الجهاز. يحدث ذلك عادةًBOARD_partitionIMAGE_PARTITION_SIZE
في إعدادات اللوحة الحالية. - إلغاء ضبط
BOARD_partitionIMAGE_PARTITION_SIZE
الحالي لجميع الأقسام فيBOARD_SUPER_PARTITION_BLOCK_DEVICES
- اضبط
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;
للاطّلاع على عمليات الضبط الأخرى، يُرجى الرجوع إلى تنفيذ الأقسام الديناميكية على الأجهزة الجديدة.
لمزيد من المعلومات حول تحديثات التوافق مع الإصدارات القديمة، يُرجى الاطّلاع على التحديث عبر الهواء (OTA) للأجهزة التي تستخدم بنية A/B بدون أقسام ديناميكية.
صور المصنع
بالنسبة إلى جهاز يتم إطلاقه مع توفير إمكانية استخدام الأقسام الديناميكية، تجنَّب استخدام fastboot في مساحة المستخدم لتثبيت صور المصنع، لأنّ عملية الإقلاع إلى مساحة المستخدم تستغرق وقتًا أطول من طرق التثبيت الأخرى.
لحلّ هذه المشكلة، ينشئ make dist
الآن صورة
super.img
إضافية يمكن نقلها مباشرةً إلى القسم
الفائق. ويجمع تلقائيًا محتويات الأقسام المنطقية، ما يعني أنّه يحتوي على system.img
وvendor.img
وما إلى ذلك، بالإضافة إلى البيانات الوصفية الخاصة بالقسم super
. يمكن نقل هذه الصورة مباشرةً إلى القسم super
بدون أي أدوات إضافية أو استخدام fastbootd. بعد اكتمال عملية الإنشاء، يتم وضع super.img
في ${ANDROID_PRODUCT_OUT}
.
بالنسبة إلى أجهزة A/B التي يتم تشغيلها باستخدام الأقسام الديناميكية، يحتوي super.img
على صور في الفتحة A. بعد نقل صورة super مباشرةً، ضَع علامة على الفتحة A باعتبارها قابلة للتشغيل قبل إعادة تشغيل الجهاز.
بالنسبة إلى الأجهزة التي تم تعديلها، ينشئ make dist
مجموعة من صور super_*.img
التي يمكن نقلها مباشرةً إلى الأقسام المادية المقابلة. على سبيل المثال، تنشئ make dist
super_system.img
وsuper_vendor.img
عندما تكون BOARD_SUPER_PARTITION_BLOCK_DEVICES
هي مورّد النظام. يتم وضع هذه الصور في مجلد OTA في
target_files.zip
.
ضبط جهاز التخزين في أداة Device Mapper
تستوعب عملية التقسيم الديناميكي عددًا من عناصر device-mapper غير المحدّدة. وقد لا يتم إنشاء مثيل لجميع هذه الأقسام على النحو المتوقّع، لذا عليك تتبُّع جميع عمليات الربط وتعديل خصائص 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
بتوسيع خصائص Android كجزء من القواعد، ويمكن ضبط أجهزة التخزين من خلال النظام الأساسي حسب الحاجة باستخدام أوامر مثل ما يلي:
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
. يمكنك توقّع أن يكون
الإعداد التلقائي للنواة read_ahead_kb
كافيًا إلى أن
تتمكّن البرامج النصية init.rc
من إلغاء الإعداد في early-fs
(عندما
تبدأ العديد من البرامج الخفية والمرافق). لذلك، تنصح Google باستخدام الميزة on property
مع عنصر تحكّم init.rc
مثل sys.read_ahead_kb
للتعامل مع توقيت العمليات ومنع حالات التنافس، كما في الأمثلة التالية:
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}