הטמעת מחיצות דינמיות

חלוקה דינמית מיושמת באמצעות מודול dm-linear device-mapper בקרנל של לינוקס. מחיצת super מכילה מטא נתונים המפרטים את השמות וטווחי הבלוק של כל מחיצה דינמית בתוך super . במהלך init בשלב הראשון, מטא-נתונים אלה מנותחים ומאומתים, ויוצרים התקני בלוק וירטואליים כדי לייצג כל מחיצה דינמית.

בעת החלת OTA, מחיצות דינמיות נוצרות אוטומטית, משנות את הגודל או נמחקות לפי הצורך. עבור התקני A/B, ישנם שני עותקים של המטא נתונים, והשינויים מוחלים רק על העותק המייצג את חריץ היעד.

מכיוון שמחיצות דינמיות מיושמות במרחב המשתמש, לא ניתן להפוך את המחיצות הנדרשות על ידי טוען האתחול לדינמיות. לדוגמה, boot , dtbo ו- vbmeta נקראים על ידי טוען האתחול, ולכן חייבים להישאר כמחיצות פיזיות.

כל מחיצה דינמית יכולה להשתייך לקבוצת עדכונים . קבוצות אלו מגבילות את השטח המרבי שהמחיצות בקבוצה זו יכולות לצרוך. לדוגמה, system vendor יכולים להשתייך לקבוצה המגבילה את הגודל הכולל של system vendor .

הטמעת מחיצות דינמיות במכשירים חדשים

סעיף זה מפרט כיצד ליישם מחיצות דינמיות במכשירים חדשים המופעלים עם אנדרואיד 10 ואילך. כדי לעדכן מכשירים קיימים, ראה שדרוג מכשירי אנדרואיד .

שינויים במחיצה

עבור מכשירים המופעלים עם אנדרואיד 10, צור מחיצה בשם super . מחיצת super מטפלת בחריצי A/B באופן פנימי, כך שמכשירי A/B אינם צריכים מחיצות super_a ו- super_b נפרדות. כל מחיצות AOSP לקריאה בלבד שאינן בשימוש על ידי טוען האתחול חייבות להיות דינמיות ויש להסירן מטבלת המחיצות של GUID (GPT). מחיצות ספציפיות לספק אינן חייבות להיות דינמיות ויכולות להיות ממוקמות ב-GPT.

כדי להעריך את גודל super , הוסף את הגדלים של המחיצות הנמחקות מה-GPT. עבור התקני A/B, זה צריך לכלול את הגודל של שני החריצים. איור 1 מציג טבלת מחיצות לדוגמה לפני ואחרי המרה למחיצות דינמיות.

פריסת טבלת מחיצות
איור 1. פריסת טבלת מחיצות פיזית חדשה בעת המרה למחיצות דינמיות

המחיצות הדינמיות הנתמכות הן:

  • מערכת
  • מוֹכֵר
  • מוצר
  • מערכת שלוחה
  • ODM

עבור מכשירים המופעלים עם Android 10, אפשרות שורת הפקודה של הליבה androidboot.super_partition חייבת להיות ריקה כך שהפקודה sysprop ro.boot.super_partition תהיה ריקה.

יישור מחיצה

מודול מיפוי ההתקן עשוי לפעול פחות ביעילות אם מחיצת super אינה מיושרת כראוי. על מחיצת super להיות מיושרת לגודל בקשת ה-I/O המינימלי כפי שנקבע על ידי שכבת הבלוק. כברירת מחדל, מערכת ה-build (באמצעות 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

שינויים בתצורת הלוח

אתה נדרש להגדיר את גודל מחיצת super :

BOARD_SUPER_PARTITION_SIZE := <size-in-bytes>

בהתקני A/B, מערכת ה-build זורקת שגיאה אם ​​הגודל הכולל של תמונות מחיצה דינמיות הוא יותר ממחצית מגודל מחיצת 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 ​​והתקני A/B מתאימים, סכום הגדלים המרביים של כל הקבוצות חייב להיות:
    BOARD_SUPER_PARTITION_SIZE - תקורה
  • בזמן הבנייה, סכום הגדלים של התמונות של כל מחיצה בקבוצת עדכון לא יעלה על הגודל המרבי של הקבוצה.
  • תקורה נדרשת בחישוב כדי לקחת בחשבון מטא נתונים, יישורים וכן הלאה. תקורה סבירה היא 4 MiB, אבל אתה יכול לבחור תקורה גדולה יותר לפי הצורך במכשיר.

גודל מחיצות דינמיות

לפני המחיצות הדינמיות, גדלי המחיצות הוקצו יתר על המידה כדי להבטיח שיש להם מספיק מקום לעדכונים עתידיים. הגודל האמיתי נלקח כפי שהוא ולרוב המחיצות לקריאה בלבד הייתה כמות מסוימת של שטח פנוי במערכת הקבצים שלהן. במחיצות דינמיות, השטח הפנוי הזה אינו שמיש וניתן להשתמש בו כדי לגדל מחיצות במהלך OTA. זה קריטי להבטיח שהמחיצות אינן מבזבזות מקום והן מוקצות לגודל מינימלי אפשרי.

עבור תמונות ext4 לקריאה בלבד, מערכת הבנייה מקצה אוטומטית את הגודל המינימלי אם לא צוין גודל מחיצה מקודדת. מערכת ה-build מתאימה לתמונה כך שלמערכת הקבצים יש כמה שפחות שטח לא מנוצל. זה מבטיח שהמכשיר לא מבזבז מקום שניתן להשתמש בו עבור 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 MiB של שטח לא בשימוש.

שינויים במערכת כשורש

למכשירים המופעלים עם אנדרואיד 10 אסור להשתמש במערכת כשורש.

למכשירים עם מחיצות דינמיות (בין אם הוא מופעל עם מחיצות דינמיות או התאמה מחדש) אסור להשתמש במערכת כשורש. ליבת לינוקס לא יכולה לפרש את מחיצת super ולכן לא יכולה להעלות system עצמה. system מותקנת כעת על ידי init שלב ראשון, שנמצא ב-ramdisk.

אל תגדיר BOARD_BUILD_SYSTEM_ROOT_IMAGE . באנדרואיד 10, הדגל BOARD_BUILD_SYSTEM_ROOT_IMAGE משמש רק כדי להבדיל אם המערכת מותאמת על ידי הליבה או על ידי init בשלב הראשון ב-ramdisk.

הגדרת BOARD_BUILD_SYSTEM_ROOT_IMAGE ל- true גורמת לשגיאת בנייה כאשר PRODUCT_USE_DYNAMIC_PARTITIONS הוא גם true .

כאשר BOARD_USES_RECOVERY_AS_BOOT מוגדר כ-true, תמונת השחזור בנויה כ-boot.img, המכילה את ה-ramdisk של השחזור. בעבר, טוען האתחול השתמש בפרמטר שורת הפקודה skip_initramfs kernel כדי להחליט לאיזה מצב לאתחל. עבור מכשירי אנדרואיד 10, אסור ל-bootloader להעביר skip_initramfs לשורת הפקודה של הליבה. במקום זאת, טוען האתחול אמור להעביר androidboot.force_normal_boot=1 כדי לדלג על שחזור ולאתחל אנדרואיד רגילה. מכשירים המופעלים עם 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

אם טוען האתחול הטמיע libavb , כלול את התיקונים הבאים:

אם אתה משתמש במחיצות משורשרות, כלול תיקון נוסף:

  • 49936b4c0109411fdd38bd4ba3a32a01c40439a9 — "libavb: תמיכה ב-vbmeta blobs בתחילת המחיצה."

שינויים בשורת הפקודה של הליבה

יש להוסיף פרמטר חדש, androidboot.boot_devices , לשורת הפקודה של הליבה. זה משמש על ידי init כדי לאפשר /dev/block/by-name קישורים סימליים. זה צריך להיות רכיב נתיב ההתקן ל-Symlink הבסיסי בשם By שנוצר על ידי ueventd , כלומר /dev/block/platform/ device-path /by-name/ partition-name . מכשירים המופעלים עם Android 12 ואילך חייבים להשתמש ב-bootconfig כדי להעביר androidboot.boot_devices ל- init .

לדוגמה, אם ה-Symlink של המחיצה העל היא /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 , שהוצג באנדרואיד 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 . לדוגמה, אם ה-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

עבור מפתחים המשתמשים ב-eng או userdebug builds, adb remount שימושי ביותר עבור איטרציה מהירה. מחיצות דינמיות מהוות בעיה עבור adb remount מכיוון שכבר אין מקום פנוי בכל מערכת קבצים. כדי לטפל בזה, מכשירים יכולים לאפשר שכבות-על. כל עוד יש מקום פנוי בתוך מחיצת העל, adb remount יוצר אוטומטית מחיצה דינמית זמנית ומשתמש בשכבות על לכתיבה. המחיצה הזמנית נקראת scratch , אז אל תשתמש בשם זה עבור מחיצות אחרות.

למידע נוסף על אופן הפעלת שכבות-על, עיין בשכבות-העל README ב-AOSP.

שדרג מכשירי אנדרואיד

אם אתה משדרג מכשיר לאנדרואיד 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 ללא מחיצות דינמיות .

תמונות מפעל

עבור מכשיר המופעל עם תמיכה במחיצות דינמיות, הימנע משימוש ב-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 builds super_system.img ו- super_vendor.img כאשר BOARD_SUPER_PARTITION_BLOCK_DEVICES הוא ספק המערכת. תמונות אלו ממוקמות בתיקיית OTA ב- target_files.zip .

ממפה התקנים - כוונון התקני אחסון

חלוקה דינמית מתאימה למספר אובייקטים לא דטרמיניסטיים של מיפוי התקנים. ייתכן שלא כולן יופיעו כצפוי, לכן עליך לעקוב אחר כל הרכיבים ולעדכן את מאפייני האנדרואיד של כל המחיצות המשויכות עם התקני האחסון הבסיסיים שלהן.

מנגנון בתוך init עוקב אחר הרכיבים ומעדכן באופן אסינכרוני את מאפייני האנדרואיד. משך הזמן שזה לוקח לא מובטח בתוך תקופה מסוימת, לכן עליך לספק מספיק זמן כדי שכל הגורמים המפעילים 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 מאפשרת להרחיב את מאפייני האנדרואיד כחלק מהכללים, וניתן לכוון התקני אחסון על ידי הפלטפורמה לפי הצורך עם פקודות כמו אלה:

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 (כאשר דמונים ומתקנים שונים מתחילים). לכן, גוגל ממליצה להשתמש בתכונה 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}