حجم الصفحة 16 كيلوبايت

حجم الصفحة هو الدقة التي يدير بها نظام التشغيل الذاكرة. تتوافق معظم وحدات المعالجة المركزية (CPU) في الوقت الحالي مع حجم صفحة 4 كيلوبايت، لذا تم برمجة نظام التشغيل Android وتطبيقاته سابقًا وتحسينها لتعمل بحجم صفحة 4 كيلوبايت. تتوافق معالجات ARM المركزية مع حجم الصفحة الأكبر الذي يبلغ 16 كيلوبايت، وبدءًا من الإصدار 15 من Android، يتيح إطار عمل AOSP إمكانية إنشاء نظام Android باستخدام حجم صفحة يبلغ 16 كيلوبايت أيضًا. يستخدم هذا الخيار ذاكرة إضافية، ولكنه يحسن أداء النظام. اعتبارًا من الإصدار 15 من Android، لم يكن هذا الخيار مفعَّلاً بشكلٍ تلقائي، ولكنه متاح كخيار في وضع المطوّر أو كخيار للمطوّرين لدى المصنّعين الأصليين للأجهزة ومطوّري التطبيقات من أجل الاستعداد للتبديل إلى وضع 16 كيلوبايت في كل مكان في المستقبل.

يتيح الإصدار 15 من نظام التشغيل Android والإصدارات الأحدث إنشاء نظام التشغيل 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 := true
  • PRODUCT_MAX_PAGE_SIZE_SUPPORTED := 16384

لإنشاء مكتبات مشترَكة ليست جزءًا من مشروع Android، عليك ضبط علامة الربط هذه:

-Wl,-z,max-page-size=16384

التحقّق من الملفات الثنائية والتطبيقات المُسبقة الإنشاء لمحاذاة ELF بحجم 16 كيلوبايت

إنّ أفضل طريقة للتحقّق من المواءمة وسلوك وقت التشغيل هي اختبار التطبيق وتشغيله على ملف برمجي لنواة مكوّنة من 16 كيلوبايت. ومع ذلك، لرصد بعض المشاكل في وقت مبكر، يُرجى اتّباع الخطوات التالية:

  • بدءًا من الإصدار 16 من Android (الإصدار التجريبي من AOSP)، يمكنك ضبط 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 والإصدارات الأحدث.