חלוקה דינמית מיושמת באמצעות מודול 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 מציג טבלת מחיצות לדוגמה לפני ואחרי המרה למחיצות דינמיות.
המחיצות הדינמיות הנתמכות הן:
- מערכת
- מוֹכֵר
- מוצר
- מערכת שלוחה
- 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 , כלול את התיקונים הבאים:
- 818cf56740775446285466eda984acedd4baeac0 — "libavb: שאילתות רק GUIDs למחיצות כאשר ה-cmdline צריך אותם."
- 5abd6bc2578968d24406d834471adfd995a0c2e9 — "אפשר למחיצת מערכת להיעדר"
- 9ba3b6613b4e5130fa01a11d984c6b5f0eb3af05 — "תקן את AvbSlotVerifyData->cmdline עשוי להיות NULL"
אם אתה משתמש במחיצות משורשרות, כלול תיקון נוסף:
- 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}