حجم الصفحة هو مستوى التفصيل الذي يدير به نظام التشغيل الذاكرة. تتوافق معظم وحدات المعالجة المركزية اليوم مع حجم الصفحة البالغ 4 كيلوبايت، لذا تم في السابق إنشاء نظام التشغيل Android والتطبيقات وتحسينها للعمل مع حجم الصفحة البالغ 4 كيلوبايت. تتوافق وحدات المعالجة المركزية ARM مع حجم الصفحة الأكبر البالغ 16 كيلوبايت، وبدءًا من Android 15، يتيح مشروع Android مفتوح المصدر (AOSP) إمكانية إنشاء Android بحجم صفحة يبلغ 16 كيلوبايت أيضًا. يستخدم هذا الخيار ذاكرة إضافية، ولكنه يحسّن أداء النظام. اعتبارًا من Android 15، لا يكون هذا الخيار مفعّلاً تلقائيًا، ولكنه متاح كوضع مطور البرامج أو خيار للمطوّرين لمصنّعي المعدات الأصلية ومطوّري التطبيقات للاستعداد للتبديل إلى الوضع 16 كيلوبايت في كل مكان في المستقبل.
يتيح Android 15 والإصدارات الأحدث إمكانية إنشاء
Android بمحاذاة ELF بحجم 16 كيلوبايت، ما يتوافق مع النواة بحجم 4 كيلوبايت و
16 كيلوبايت بدءًا من
android14-6.1.
عند استخدام هذا الإعداد مع نواة بحجم 16 كيلوبايت، يستخدم ذاكرة إضافية ولكنه يحسّن أداء النظام.
ضبط Android على 16 كيلوبايت
لا تتوافق الصفحات بحجم 16 كيلوبايت إلا مع أهداف arm64 التي تستخدم نواة بحجم 16 كيلوبايت.
ومع ذلك، هناك أيضًا خيار لـ
محاكاة مساحة المستخدم بحجم 16 كيلوبايت على x86_64 لجهاز Cuttlefish.
مساحة النواة
بالنسبة إلى أهداف arm64، إذا كنت تستخدم
Kleaf
لإنشاء النواة، فإنّ --page_size=16k ينشئ النواة في الوضع 16 كيلوبايت.
إذا كنت تستخدم إعدادات نواة Linux مباشرةً، يمكنك اختيار صفحات بحجم 16 كيلوبايت من خلال ضبط CONFIG_ARM64_16K_PAGES بدلاً من CONFIG_ARM64_4K_PAGES.
مساحة المستخدم
لتفعيل التوافق مع حجم الصفحة البالغ 16 كيلوبايت في مساحة مستخدم Android، اضبط خيارات الإنشاء التالية على منتجك:
PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO := trueيزيل تعريفPAGE_SIZE، ويجعل المكوّنات تحدّد حجم الصفحة في وقت التشغيل.PRODUCT_MAX_PAGE_SIZE_SUPPORTED := 16384يضمن إنشاء ملفات ELF للنظام الأساسي بمحاذاة 16 كيلوبايت. هذا الحجم الأكبر من اللازم هو لـ تحقيق التوافق في المستقبل. باستخدام محاذاة ELF بحجم 16 كيلوبايت، يمكن للنواة أن تتوافق مع أحجام الصفحات 4 كيلوبايت و16 كيلوبايت.
التحقّق من علامات الإنشاء
بعد اختيار هدف lunch، تأكَّد من إعداد علامات الإنشاء بشكلٍ صحيح في البيئة:
$ source build/envsetup.sh
$ lunch target
$ get_build_var TARGET_MAX_PAGE_SIZE_SUPPORTED
16384
$ get_build_var TARGET_NO_BIONIC_PAGE_SIZE_MACRO
true
إذا عرض الأمران السابقان 16384 وtrue على التوالي، يعني ذلك أنّ علامات الإنشاء تم إعدادها بشكلٍ صحيح للعمل مع نواة بحجم 16 كيلوبايت. ومع ذلك، حتى إذا نجحت عملية الإنشاء، قد تظل هناك مشاكل في وقت التشغيل بسبب الاختلافات في بيئة 16 كيلوبايت.
برمجة النظام بحجم الصفحة 16 كيلوبايت
لا يتعامل الجزء الأكبر من الرموز البرمجية على أي جهاز يعمل بنظام التشغيل Android مباشرةً مع حجم الصفحة. ومع ذلك، بالنسبة إلى الرموز البرمجية التي تتعامل مع الصفحات، يتغيّر سلوك النواة في تخصيص الذاكرة، وعليك أخذ ذلك في الاعتبار لكتابة رموز برمجية ليست متوافقة فحسب، بل أيضًا عالية الأداء قدر الإمكان وتستخدم أقل قدر ممكن من الموارد.
إذا طلبت mmap على منطقة بحجم 1 كيلوبايت أو 2 كيلوبايت أو ما يصل إلى 4 كيلوبايت على نظام بحجم 4 كيلوبايت، سيحجز النظام 4 كيلوبايت لتنفيذ ذلك. بعبارة أخرى، عند طلب ذاكرة من النواة، يجب أن تقرّب النواة دائمًا الذاكرة المطلوبة إلى أقرب حجم صفحة. على سبيل المثال، إذا خصّصت منطقة بحجم 5 كيلوبايت على منطقة بحجم 4 كيلوبايت، ستخصّص النواة 8 كيلوبايت.
في النواة بحجم 16 كيلوبايت، تكون "الأطراف الخلفية" الإضافية للصفحات أكبر. على سبيل المثال، ستخصّص كل عمليات التخصيص هذه، من 1 كيلوبايت إلى 5 كيلوبايت، 16 كيلوبايت عند استخدامها مع نواة بحجم 16 كيلوبايت. إذا طلبت 17 كيلوبايت، سيتم تخصيص 32 كيلوبايت.
على سبيل المثال، على نظام بحجم 4 كيلوبايت، لا بأس بتخصيص منطقتَين مجهولتين للقراءة والكتابة بحجم 4 كيلوبايت. ومع ذلك، على نواة بحجم 16 كيلوبايت، سيؤدي ذلك إلى تخصيص صفحتَين أو 32 كيلوبايت. على نواة بحجم 16 كيلوبايت، يمكن دمج هاتَين المنطقتَين في صفحة واحدة قابلة للقراءة أو الكتابة قدر الإمكان، بحيث يتم استخدام 16 كيلوبايت فقط، ما يؤدي إلى إهدار 8 كيلوبايت مقارنةً بحالة النواة بحجم 4 كيلوبايت. لتقليل استخدام الذاكرة بشكلٍ أكبر، يمكن دمج المزيد من الصفحات. في الواقع، على نظام بحجم 16 كيلوبايت تم تحسينه إلى أقصى حد، تتطلب الصفحات بحجم 16 كيلوبايت ذاكرة أقل من الأنظمة بحجم 4 كيلوبايت لأنّ جدول الصفحات يمثّل ربع حجم الذاكرة نفسها.
عند استخدام mmap، تأكَّد من تقريب الحجم الذي تطلبه إلى أقرب حجم صفحة. يضمن ذلك أن يكون مقدار الذاكرة الكامل الذي تخصّصه النواة مرئيًا مباشرةً لمساحة المستخدم في قيم وقت التشغيل، بدلاً من أن يتم طلبه ضمنيًا أو أن يكون الوصول إليه ضمنيًا أو عن طريق الخطأ.
إنشاء مكتبات مشتركة بمحاذاة ELF بحجم 16 كيلوبايت
لإنشاء مكتبات مشتركة تشكّل جزءًا من مشروع Android، تكون الإعدادات السابقة في تفعيل حجم الصفحة 16 كيلوبايت كافية:
PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO := truePRODUCT_MAX_PAGE_SIZE_SUPPORTED := 16384
لإنشاء مكتبات مشتركة لا تشكّل جزءًا من مشروع Android، عليك تمرير علامة الرابط هذه:
-Wl,-z,max-page-size=16384
التحقّق من الملفات الثنائية والملفات المُنشأة مسبقًا لمحاذاة ELF بحجم 16 كيلوبايت
أفضل طريقة للتحقّق من المحاذاة وسلوك وقت التشغيل هي الاختبار والتشغيل على نواة مُجمَّعة بحجم 16 كيلوبايت. ومع ذلك، من أجل رصد بعض المشاكل في وقت مبكر:
بدءًا من Android 16، يمكنك ضبط
PRODUCT_CHECK_PREBUILT_MAX_PAGE_SIZE := trueفي وقت الإنشاء. استخدِمignore_max_page_size: trueفيAndroid.bpوLOCAL_IGNORE_MAX_PAGE_SIZE := trueفيAndroid.mkلتجاهلها مؤقتًا. تتحقّق هذه الإعدادات من جميع الملفات المُنشأة مسبقًا وتسمح لك برصد الحالات التي يتم فيها تحديث أحد هذه الملفات ولكن لا تتم محاذاته بحجم 16 كيلوبايت.يمكنك تشغيل
atest elf_alignment_testالذي يتحقّق من محاذاة ملفات ELF على الجهاز فقط على الأجهزة التي يتم تشغيلها باستخدام Android 15 والإصدارات الأحدث.