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

الأقسام الديناميكية المدعومة هي:
- نظام
- بائع
- منتج
- تحويلة النظام
- التصميم
بالنسبة للأجهزة التي تعمل بنظام Android 10 ، يجب أن يكون خيار سطر أوامر kernel androidboot.super_partition
فارغًا بحيث يكون الأمر sysprop 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
- النفقات العامة
انظر تنفيذ Virtual A / B. - بالنسبة لأجهزة تشغيل A / B ، يجب أن يكون مجموع الأحجام القصوى لجميع المجموعات:
BOARD_SUPER_PARTITION_SIZE
/ 2 - النفقات العامة - بالنسبة للأجهزة غير A / B وأجهزة A / B المعدلة ، يجب أن يكون مجموع الأحجام القصوى لجميع المجموعات:
BOARD_SUPER_PARTITION_SIZE
- النفقات العامة - في وقت الإنشاء ، يجب ألا يتجاوز مجموع أحجام الصور لكل قسم في مجموعة التحديث الحد الأقصى لحجم المجموعة.
- النفقات العامة مطلوبة في الحساب لحساب البيانات الوصفية والمحاذاة وما إلى ذلك. الحمل المعقول هو 4 ميغا بايت ، ولكن يمكنك اختيار حمل أكبر حسب حاجة الجهاز.
تحجيم الأقسام الديناميكية
قبل الأقسام الديناميكية ، تم تخصيص أحجام الأقسام بشكل زائد لضمان توفر مساحة كافية للتحديثات المستقبلية. تم أخذ الحجم الفعلي كما هو ومعظم أقسام القراءة فقط بها قدر من المساحة الحرة في نظام الملفات الخاص بها. في الأقسام الديناميكية ، هذه المساحة الخالية غير قابلة للاستخدام ويمكن استخدامها لتنمية الأقسام أثناء OTA. من الأهمية بمكان التأكد من أن الأقسام لا تهدر المساحة وأن يتم تخصيصها لأدنى حجم ممكن.
بالنسبة لصور ext4 للقراءة فقط ، يقوم نظام الإنشاء تلقائيًا بتخصيص الحد الأدنى للحجم إذا لم يتم تحديد حجم قسم مشفر. يلائم نظام الإنشاء الصورة بحيث يحتوي نظام الملفات على أقل مساحة غير مستخدمة قدر الإمكان. هذا يضمن أن الجهاز لا يضيع مساحة يمكن استخدامها في OTAs.
بالإضافة إلى ذلك ، يمكن ضغط صور ext4 بشكل أكبر عن طريق تمكين إلغاء التكرار على مستوى الكتلة. لتمكين هذا ، استخدم التكوين التالي:
BOARD_EXT4_SHARE_DUP_BLOCKS := true
إذا كان التخصيص التلقائي للحد الأدنى لحجم القسم غير مرغوب فيه ، فهناك طريقتان للتحكم في حجم القسم. يمكنك تحديد الحد الأدنى من المساحة الخالية باستخدام BOARD_ partition IMAGE_PARTITION_RESERVED_SIZE
، أو يمكنك تحديد BOARD_ partition IMAGE_PARTITION_SIZE
لفرض الأقسام الديناميكية على حجم معين. لا ينصح بأي من هذه إلا إذا لزم الأمر.
فمثلا:
BOARD_PRODUCTIMAGE_PARTITION_RESERVED_SIZE := 52428800
هذا يفرض على نظام الملفات في product.img
أن يحتوي على 50 ميغا بايت من المساحة غير المستخدمة.
تغييرات النظام كجذر
يجب ألا تستخدم الأجهزة التي تعمل بنظام Android 10 نظام الجذر.
يجب ألا تستخدم الأجهزة ذات الأقسام الديناميكية (سواء تم تشغيلها باستخدام الأقسام الديناميكية أو تعديلها التحديثي) النظام كجذر. لا تستطيع نواة Linux تفسير القسم super
وبالتالي لا يمكنها تحميل system
نفسه. يتم الآن تثبيت system
بواسطة init
من المرحلة الأولى ، والتي توجد في ramdisk.
لا تقم بتعيين BOARD_BUILD_SYSTEM_ROOT_IMAGE
. في Android 10 ، تُستخدم علامة BOARD_BUILD_SYSTEM_ROOT_IMAGE
فقط للتمييز بين ما إذا كان النظام مثبتًا بواسطة kernel أم عن طريق بدء المرحلة الأولى في init
.
يؤدي تعيين BOARD_BUILD_SYSTEM_ROOT_IMAGE
على القيمة true
إلى حدوث خطأ في الإصدار عندما يكون PRODUCT_USE_DYNAMIC_PARTITIONS
true
أيضًا.
عندما يتم تعيين BOARD_USES_RECOVERY_AS_BOOT
على true ، يتم إنشاء صورة الاسترداد كـ boot.img ، التي تحتوي على قرص ذاكرة الوصول العشوائي الخاص بالاسترداد. في السابق ، استخدم برنامج bootloader معلمة سطر أوامر kernel skip_initramfs
لتحديد الوضع الذي سيتم التمهيد فيه. بالنسبة لأجهزة Android 10 ، يجب ألا يقوم برنامج bootloader بتمرير skip_initramfs
إلى سطر أوامر kernel. بدلاً من ذلك ، يجب أن يمر برنامج bootloader androidboot.force_normal_boot=1
لتخطي الاسترداد وتمهيد Android العادي. يجب أن تستخدم الأجهزة التي يتم تشغيلها مع Android 12 أو إصدار أحدث bootconfig لتمرير androidboot.force_normal_boot=1
.
تغييرات تكوين AVB
عند استخدام Android Verified Boot 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
إذا كان برنامج bootloader يحتوي على libavb ، فقم بتضمين التصحيحات التالية:
- 818cf56740775446285466eda984acedd4baeac0 - "libavb: استعلام عن معرفات GUID للقسم فقط عندما يحتاجها cmdline."
- 5abd6bc2578968d24406d834471adfd995a0c2e9 - "السماح بتغيب قسم النظام"
- 9ba3b6613b4e5130fa01a11d984c6b5f0eb3af05 - "إصلاح AvbSlotVerifyData-> قد يكون cmdline فارغًا"
في حالة استخدام أقسام متسلسلة ، قم بتضمين تصحيح إضافي:
- 49936b4c0109411fdd38bd4ba3a32a01c40439a9 - "libavb: دعم نقاط vbmeta في بداية القسم."
يتغير سطر أوامر Kernel
يجب إضافة معامل جديد ، androidboot.boot_devices
، إلى سطر أوامر kernel. يتم استخدام هذا بواسطة init
لتمكين /dev/block/by-name
. يجب أن يكون مكون مسار الجهاز للرابط الرمزي الأساسي الذي تم إنشاؤه بواسطة ueventd
، أي /dev/block/platform/ device-path /by-name/ partition-name
. يجب أن تستخدم الأجهزة التي يتم تشغيلها بنظام Android 12 أو إصدار أحدث 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يمكنك إضافة معلمة bootconfig في ملف BoardConfig.mk على النحو التالي:
BOARD_BOOTCONFIG += androidboot.boot_devices=soc/100000.ufshc
التغييرات fstab
يجب ألا تحتوي تراكبات شجرة الجهاز وشجرة الجهاز على إدخالات fstab. استخدم ملف fstab الذي سيكون جزءًا من ramdisk.
يجب إجراء التغييرات على ملف fstab للأقسام المنطقية:
- يجب أن يشتمل حقل fs_mgr flags على العلم
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
. على سبيل المثال ، إذا كان الرابط الرمزي للقسم الفائق هو /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
لا يفهم برنامج bootloader (أو أي أداة فلاش خاصة بمساحة المستخدمين) الأقسام الديناميكية ، لذا لا يمكنه وميضها. لمعالجة هذا الأمر ، يجب أن تستخدم الأجهزة تطبيق مساحة المستخدم لبروتوكول Fastboot ، المسمى fastbootd.
لمزيد من المعلومات حول كيفية تنفيذ fastbootd ، راجع نقل Fastboot إلى مساحة المستخدم .
adb remount
للمطورين الذين يستخدمون تصميمات eng أو userdebug ، يعد adb adb remount
مفيدًا للغاية للتكرار السريع. تشكل الأقسام الديناميكية مشكلة في adb remount
لأنه لم يعد هناك مساحة خالية داخل كل نظام ملفات. لمعالجة هذا الأمر ، يمكن للأجهزة تمكين التراكبات. طالما توجد مساحة خالية داخل القسم الفائق ، يقوم adb adb remount
تلقائيًا بإنشاء قسم ديناميكي مؤقت ويستخدم تراكبات للكتابة. يُطلق على القسم المؤقت اسم scratch
، لذا لا تستخدم هذا الاسم للأقسام الأخرى.
لمزيد من المعلومات حول كيفية تمكين التراكبات ، راجع التراكبات README في AOSP.
ترقية أجهزة Android
إذا قمت بترقية جهاز إلى Android 10 ، وأردت تضمين دعم الأقسام الديناميكية في OTA ، فلن تحتاج إلى تغيير جدول الأقسام المدمج. مطلوب بعض التكوين الإضافي.
تغييرات تكوين الجهاز
لتعديل التقسيم الديناميكي ، أضف العلامات التالية في 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_ partition IMAGE_PARTITION_SIZE
في تكوينات اللوحة الحالية. - قم بإلغاء
BOARD_ partition IMAGE_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
إضافية يمكن وميضها مباشرةً إلى القسم super. يقوم تلقائيًا بتجميع محتويات الأقسام المنطقية ، مما يعني أنه يحتوي على system.img
و vendor.img
وما إلى ذلك ، بالإضافة إلى البيانات الوصفية للقسم super
. يمكن وميض هذه الصورة مباشرة إلى القسم super
دون أي أدوات إضافية أو استخدام fastbootd. بعد الإنشاء ، تم وضع super.img
في ${ANDROID_PRODUCT_OUT}
.
بالنسبة لأجهزة A / B التي يتم تشغيلها باستخدام أقسام ديناميكية ، يحتوي super.img
على صور في الفتحة A. بعد وميض الصورة الفائقة مباشرة ، ضع علامة على الفتحة A على أنها قابلة للتمهيد قبل إعادة تشغيل الجهاز.
بالنسبة للأجهزة المعدلة ، make dist
builds مجموعة من الصور super_*.img
التي يمكن وميضها مباشرة إلى الأقسام المادية المقابلة. على سبيل المثال ، make dist
builds 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
بمجرد أن تبدأ معالجة الأمر في المرحلة الثانية ، فإن epoll loop
init
نشطة ، وتبدأ القيم في التحديث. ومع ذلك ، نظرًا لأن مشغلات الخاصية ليست نشطة حتى وقت init
، لا يمكن استخدامها في مراحل التمهيد الأولية للتعامل مع root
أو system
أو vendor
. قد تتوقع أن يكون kernel الافتراضي 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}