تنفيذ الأقسام الديناميكية

تنفيذ التقسيم الديناميكي باستخدام أداة تخطيط الأجهزة الخطية بنظام dm في نواة Linux. يحتوي القسم super على البيانات الوصفية التي تسرد أسماء كل قسم ديناميكي ونطاقات الحظر في حدود super. خلال المرحلة الأولى من init، سيتم تحليل بيانات التعريف والتحقق من صحتها، ويتم إنشاء أجهزة الكتل الافتراضية لتمثيل كل قسم ديناميكي.

عند تطبيق التحديث عبر الهواء، يتم إنشاء أقسام ديناميكية تلقائيًا، أو تغيير حجمها أو حذفها حسب الحاجة. بالنسبة لأجهزة 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 للقراءة فقط ولا تستخدمها برنامج الإقلاع أن تكون ديناميكية ويجب إزالتها من جدول تقسيم المعرّف الفريد العالمي (GPT). لا يجب أن تكون الأقسام الخاصة بالمورّدين ديناميكية، ويمكن وضعها في جدول تقسيم المعرّف الفريد العمومي.

لتقدير حجم super، أضِف مقاسات الأقسام التي يتم حذفها من GPT. بالنسبة لأجهزة A/B، ينطبق هذا حجم كلتا الخانتين. يوضّح الشكل 1 مثال لجدول التقسيم قبل وبعد التحويل إلى التحويل الديناميكي الأقسام.

تنسيق جدول التقسيم
الشكل 1. تنسيق جدول تقسيم فعلي جديد عند التحويل إلى أقسام ديناميكية

الأقسام الديناميكية المتوافقة هي:

  • النظام
  • المورّد
  • المنتَج
  • ملحقات النظام
  • ODM

بالنسبة إلى الأجهزة التي تعمل بنظام التشغيل Android 10، سيتم تطبيق خيار سطر أوامر النواة androidboot.super_partition فارغًا بحيث يمكن للأمر sys تلك حقل ro.boot.super_partition فارغ.

محاذاة القسم

وقد تعمل وحدة خرائط الأجهزة بكفاءة أقل إذا لم تتم محاذاة قسم super بشكل صحيح. تشير رسالة الأشكال البيانية يجب محاذاة قسم super مع الحد الأدنى من وحدات الإدخال/الإخراج طلب الحجم على النحو الذي تحدده طبقة الكتلة. بشكل افتراضي، (عبر lpmake، والذي ينشئ super لصورة القسم)، تفترض أن المحاذاة بقيمة 1 ميبيبايت كافيًا لكل قسم ديناميكي ومع ذلك، يجب على البائعين تأكَّد من محاذاة قسم 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 ميبيبايت، ولكنك يمكنك اختيار زيادة أكبر حسب الحاجة بواسطة الجهاز.

حجم الأقسام الديناميكية

قبل الأقسام الديناميكية، كان يتم تخصيص أحجام الأقسام بشكل زائد والتأكد من توفر مساحة كافية لها للتحديثات المستقبلية. الحجم الفعلي على النحو المعتاد، وكان لدى معظم الأقسام المخصصة للقراءة فقط مقدارًا من البيانات المجانية مساحة في نظام الملفات الخاص بها. في الأقسام الديناميكية، تكون هذه المساحة الخالية ويمكن استخدامها لزيادة التقسيمات أثناء إجراء التحديث عبر الهواء. من الضروري التأكد من أن الأقسام لا تهدر مساحة وأنها المخصصة لأدنى حجم ممكن.

بالنسبة إلى صور ext4 للقراءة فقط، يخصِّص نظام التصميم تلقائيًا الحد الأدنى للحجم في حال عدم تحديد حجم القسم الثابت. تشير رسالة الأشكال البيانية نظام التصميم يناسب الصورة بحيث يحتوي نظام الملفات على أقل قدر ممكن مساحة غير مستخدمة قدر الإمكان. يضمن هذا عدم إهدار الجهاز المساحة التي يمكن استخدامها لوكالات السفر على الإنترنت.

ويمكن أيضًا ضغط الصور ext4 عن طريق تفعيل إزالة تكرار المستوى. لتفعيل ذلك، استخدِم الإعدادات التالية:

BOARD_EXT4_SHARE_DUP_BLOCKS := true

في حال كان التخصيص التلقائي للحد الأدنى للقسم غير مرغوب فيه، هناك طريقتان للتحكّم في حجم القسم. يمكنك تحديد الحد الأدنى من المساحة الخالية BOARD_partitionIMAGE_PARTITION_RESERVED_SIZE, أو يمكنك تحديد BOARD_partitionIMAGE_PARTITION_SIZE للفرض أقسام ديناميكية محددة إلى حجم معين. لا يهمّني أيّ منهما أوصى به إلا في حالة الضرورة.

مثلاً:

BOARD_PRODUCTIMAGE_PARTITION_RESERVED_SIZE := 52428800

يفرض ذلك على نظام الملفات في product.img مساحة تخزين غير مُستخدَمة تبلغ 50 ميغا بايت.

التغييرات في النظام كجذر

يجب ألّا تعمل الأجهزة التي تعمل بنظام التشغيل Android 10 استخدام النظام كجذر.

الأجهزة التي تحتوي على أقسام ديناميكية (سواء تم تشغيلها مع عمليات التعديل أو تم فتحها) أقسام ديناميكية) يجب ألا يستخدم النظام كجذر. لا يمكن لنواة Linux تفسير قسم super وبالتالي لا يمكن التثبيت system نفسه تم تثبيت system الآن من خلال المرحلة الأولى من "init" المتوفّرة في الهرم.

لا تضبط السمة BOARD_BUILD_SYSTEM_ROOT_IMAGE. ضِمن Android 10، تُستخدَم العلامة BOARD_BUILD_SYSTEM_ROOT_IMAGE فقط ما إذا كان النظام مثبّتًا بواسطة النواة (kernel) أو من خلال المرحلة الأولى من "init" في ramdisk.

جارٍ ضبط BOARD_BUILD_SYSTEM_ROOT_IMAGE على true إلى حدوث خطأ في الإصدار عند PRODUCT_USE_DYNAMIC_PARTITIONS هو أيضًا true.

عند ضبط BOARD_USES_RECOVERY_AS_BOOT على "صحيح"، النسخة المخصصة لاسترداد البيانات بتنسيق Boot.img، وهي تحتوي على رمكس. في السابق، كان برنامج الإقلاع يستخدم النواة skip_initramfs. سطر الأوامر لتحديد الوضع الذي يتم التمهيد فيه. بالنسبة أجهزة Android 10، يجب ألا يجتاز برنامج الإقلاع برنامج الإقلاع skip_initramfs إلى سطر أوامر النواة. ولكن بدلاً من ذلك، يجب اجتياز androidboot.force_normal_boot=1 لتخطّي عملية الاسترداد وتشغيل Android العادي. إطلاق الأجهزة التي تعمل بنظام التشغيل Android 12 أو في وقت لاحق يجب أن يستخدم Bootconfig لاجتياز androidboot.force_normal_boot=1.

تغييرات إعدادات AVB

عند استخدام Android الإصدار 2.0 من نظام التشغيل الذي تم التحقّق منه، إذا كان الجهاز لا يستخدم القسم المتسلسل واصفات البيانات، فلا يلزم إجراء أي تغيير. في حال استخدام سلاسل إلا أن أحد الأقسام التي تم التحقق منها هو قسم ديناميكي، تكون التغييرات ضرورية.

في ما يلي مثال على عملية ضبط لجهاز يستند إلى سلسلة 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، تضمين التصحيحات التالية:

في حال استخدام الأقسام المتسلسلة، يجب تضمين رمز تصحيح إضافي:

  • 49936b4c0109411fdd38bd4ba3a32a01c40439a9 — "libavb: دعم وحدات تخزين البيانات الثنائية الكبيرة vbmeta في بداية التقسيم"

تغييرات سطر أوامر Kernel

يجب إضافة مَعلمة جديدة androidboot.boot_devices. إلى سطر أوامر النواة. يتم استخدام ذلك من قِبل init من أجل لتفعيل الروابط الرمزية لـ /dev/block/by-name. يجب أن تكون مكوّن مسار الجهاز إلى الرابط الرمزي الأساسي حسب الاسم الذي تم إنشاؤه بواسطة ueventd، أي /dev/block/platform/device-path/by-name/partition-name يجب أن تستخدم الأجهزة التي تعمل بنظام التشغيل Android 12 أو الإصدارات الأحدث التمهيد لتمرير androidboot.boot_devices إلى init.

على سبيل المثال، إذا كان الرابط الرمزي الخاص بالقسم المميز حسب الاسم /dev/block/platform/soc/100000.ufshc/by-name/super, يمكنك إضافة معلمة سطر الأوامر في ملف BoardConfig.mk التالي:

BOARD_KERNEL_CMDLINE += androidboot.boot_devices=soc/100000.ufshc
يمكنك إضافة مَعلمة Bootconfig في ملف BoardConfig.mk على النحو التالي:
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 إلى المرحلة الأولى من ذاكرة القرص.

التغييرات على 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، يُرجى الاطّلاع على نقل Fastboot إلى مساحة المستخدم.

إعادة تحميل adb

للمطوّرين الذين يستخدمون إصدارات eng أو userdebug، adb remount مفيدة للغاية للتكرار السريع. تشكل الأقسام الديناميكية مشكلة في adb remount لأنه لم يعد متاحًا مساحة داخل كل نظام ملفات. لحلّ هذه المشكلة، يمكن للأجهزة تفعيل تراكبات الصور. ما دام هناك مساحة خالية داخل التقسيم الفائق، ينشئ adb remount تلقائيًا محتوى ديناميكي مؤقتًا. واستخدام تراكبات الصور في عمليات الكتابة. التقسيم المؤقت هو بالاسم scratch، لذا لا تستخدم هذا الاسم لمواقع أخرى الأقسام.

لمزيد من المعلومات حول كيفية تمكين تراكبات الصور، راجع التراكبات قراءة في AOSP.

ترقية أجهزة Android

في حال ترقية جهاز إلى Android 10 إذا كنت تريد تضمين دعم الأقسام الديناميكية في التحديث عبر الهواء، فلن تحتاج إلى تغيير جدول الأقسام المدمج. بعض التكوينات الإضافية هي مطلوبة.

التغييرات على إعدادات الجهاز

لتعديل التقسيم الديناميكي، أضف العلامات التالية في device.mk:

PRODUCT_USE_DYNAMIC_PARTITIONS := true
PRODUCT_RETROFIT_DYNAMIC_PARTITIONS := true

تغييرات إعدادات لوحة الجهاز

يُطلب منك تعيين متغيرات اللوحة التالية:

  • ضبط 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;

لمعرفة الإعدادات الأخرى، يمكنك الاطّلاع على تنفيذ الأقسام الديناميكية على الأجهزة الجديدة

لمزيد من المعلومات حول تحديثات عمليات المراجعة، راجع عبر الهواء لأجهزة A/B التي لا تتضمّن النظام الديناميكي الأقسام:

الصور الأصلية

بالنسبة إلى الأجهزة التي يتم تشغيلها والتي تتيح استخدام الأقسام الديناميكية، تجنَّب استخدام userspace Fastboot إلى صور المصنع، نظرًا لأن التمهيد في مساحة المستخدم أبطأ من طرق الوامضة الأخرى.

لمعالجة هذه المشكلة، تنشئ make dist الآن إضافة صورة super.img التي يمكن تحديثها مباشرةً إلى العنصر قسم القرص. فهو يجمع تلقائيًا محتويات العناصر المنطقية الأقسام، مما يعني أنه يحتوي على system.img، vendor.img وما إلى ذلك، بالإضافة إلى super البيانات الوصفية للأقسام. ويمكن وميض هذه الصورة مباشرةً في super بدون أي أدوات أو استخدام إضافية Fastbootd. بعد الإصدار، يتم وضع super.img في. ${ANDROID_PRODUCT_OUT}

في أجهزة A/B التي يتم تشغيلها باستخدام أقسام ديناميكية، يحتوي super.img على صور في الخانة A. بعد وميض صورة مميزة مباشرة، فقم بوضع علامة على الفتحة A كقابلة للتشغيل قبل إعادة تشغيل الخاص بك.

بالنسبة إلى الأجهزة المعدَّلة، ينشئ make dist مجموعة من super_*.img من الصور التي يمكن وميضها مباشرةً الأقسام المادية المقابلة. على سبيل المثال: make dist الإصداران super_system.img وsuper_vendor.img عندما يكون BOARD_SUPER_PARTITION_BLOCK_DEVICES هو النظام البائع. يتم وضع هذه الصور في مجلد OTA في target_files.zip

ضبط أجهزة التخزين المخصّصة لمصممي خرائط الأجهزة

يستوعب التقسيم الديناميكي عددًا من محددات الأجهزة غير المحددة الأخرى. قد لا تؤدي جميعها إلى إنشاء مثيل كما هو متوقع، لذا يجب تتبع جميع وتحديث خصائص 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}