חלוקה דינמית למחיצות (partitioning) מוטמעת באמצעות מיפוי המכשירים ל-dm-לינארי
בליבה (kernel) של Linux. המחיצה super
מכילה
מטא-נתונים שבהם מפורטים השמות וטווחי החסימה של כל מחיצה דינמית
בתוך super
. בשלב הראשון init
:
מתבצע ניתוח ואימות של המטא-נתונים, ומכשירי בלוקים וירטואליים נוצרים
שמייצגים כל מחיצה דינמית.
כשמחילים OTA, מחיצות דינמיות נוצרות באופן אוטומטי, שונתה או נמחקה לפי הצורך. במכשירי A/B יש שני עותקים של את המטא-נתונים, והשינויים יחולו רק על העותק שמייצג את משבצת היעד.
מכיוון שמחיצות דינמיות מוטמעות במרחב המשתמשים, יש צורך במחיצות
תוכנת האתחול לא יכולה להיות דינמית. לדוגמה, boot
,
הפרמטרים dtbo
ו-vbmeta
נקראים על ידי תוכנת האתחול, וגם
ולכן הן חייבות להישאר כמחיצות פיזיות.
כל מחיצה דינמית יכולה להשתייך לקבוצת עדכון. האלה
מגבילות את המקום המקסימלי שמחיצות בקבוצה זו יכולות לצרוך.
לדוגמה, system
ו-vendor
יכולים להשתייך אל
קבוצה שמגבילה את הגודל הכולל של system
ו-
vendor
.
הטמעת מחיצות דינמיות במכשירים חדשים
בקטע הזה מוסבר איך להטמיע מחיצות דינמיות במכשירים חדשים ההשקה עם Android 10 ואילך. לעדכון מכשירים קיימים, מידע נוסף זמין במאמר שדרוג של Android מכשירים.
שינויים במחיצות
במכשירים שמושקים עם Android 10, יש ליצור
מחיצה בשם super
. super
מחיצה מטפלת בחרי A/B באופן פנימי, כך שמכשירי A/B לא
הנפרדות בין מחיצות super_a
ו-super_b
.
כל מחיצות AOSP לקריאה בלבד שלא משמשות את תוכנת האתחול
להיות דינמית וצריך להסיר אותה מטבלת המחיצות של GUID (GPT).
מחיצות ספציפיות לספק לא חייבות להיות דינמיות וניתן למקם אותן
ב-GPT.
כדי להעריך את הגודל של super
, צריך להוסיף את המידות של
מחיצות שנמחקו מה-GPT. במכשירי A/B, ההגדרה הזו
לכלול את הגודל של שני המקומות. איור 1 מוצג
דוגמה לטבלת מחיצות לפני ואחרי ההמרה לדינמית
מחיצות.
המחיצות הדינמיות הנתמכות הן:
- מערכת
- ספק
- מוצר
- הרחבה למערכת
- ODM
במכשירים שמושקים עם Android 10,
אפשרות בשורת הפקודה בליבה (kernel) androidboot.super_partition
חייב להיות ריק, כך שהפקודה syspro
השדה ro.boot.super_partition
ריק.
יישור מחיצות
יכול להיות שהמודול של מיפוי המכשירים יפעל פחות ביעילות אם
המחיצה super
לא מיושרת כראוי.
המחיצה של super
חייבת להיות מותאמת לערך המינימלי של קלט/פלט (I/O)
גודל הבקשה כפי שנקבע בשכבת הבלוק. כברירת מחדל,
לבנות מערכת (דרך 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 שעברו תיקון, הסכום המקסימלי
הגודל של כל הקבוצות חייב להיות:
BOARD_SUPER_PARTITION_SIZE
– תקורה - בזמן ה-build, סכום התמונות של כל מחיצה בקבוצת עדכון לא יכולה לחרוג מהגודל המקסימלי של הקבוצה.
- תקורה נדרשת בחישוב כדי להביא בחשבון מטא-נתונים, התאמות וכו'. תקורה סבירה היא 4MiB, אבל יכול לבחור תקורה גדולה יותר לפי הצורך של המכשיר.
גודל מחיצות דינמיות
לפני מחיצות דינמיות, גדלי מחיצות הוקצו מדי לוודא שיהיה להם מספיק מקום לעדכונים עתידיים. הגודל בפועל נלקח כפי שהוא, ורוב המחיצות לקריאה בלבד היו מקום במערכת הקבצים שלהם. במחיצות דינמיות, השטח הפנוי לא ניתן לשימוש ויכולים לשמש להגדלת מחיצות במהלך OTA. חשוב לוודא שמחיצות לא מבזבזות מקום מוקצה לגודל המינימלי האפשרי.
לתמונות ext4 לקריאה בלבד, מערכת ה-build מקצה באופן אוטומטי את הגודל המינימלי אם לא צוין גודל מחיצה בתוך הקוד. מתאימה את התמונה כך שבמערכת הקבצים יש שטח בלתי מנוצל ככל האפשר. כך אפשר לוודא שהמכשיר לא מבזבז מקום שאפשר להשתמש בו עבור אפליקציות OTA.
בנוסף, אפשר לדחוס עוד יותר תמונות ext4 על ידי הפעלת בלוקים ביטול כפילויות ברמה. כדי להפעיל את האפשרות הזאת, צריך להשתמש בהגדרות הבאות:
BOARD_EXT4_SHARE_DUP_BLOCKS := true
אם הקצאה אוטומטית של גודל מינימלי של מחיצות היא לא רצויה,
יש שתי דרכים לשלוט בגודל המחיצה. אפשר לציין
שטח פנוי מינימלי עם
BOARD_partitionIMAGE_PARTITION_RESERVED_SIZE
,
או שאפשר לציין
BOARD_partitionIMAGE_PARTITION_SIZE
לאילוץ
מחיצות דינמיות לגודל ספציפי. אף אחת מהאפשרויות האלה
אלא אם יש בכך צורך.
לדוגמה:
BOARD_PRODUCTIMAGE_PARTITION_RESERVED_SIZE := 52428800
הפעולה הזו מאלצת את מערכת הקבצים ב-product.img
50MiB של נפח אחסון שלא נוצל.
שינויי מערכת ברמה הבסיסית (root)
במכשירים שמושקים עם Android 10 אסור להשתמש במערכת בתור הרמה הבסיסית (root).
מכשירים עם מחיצות דינמיות (בין אם מדובר בהשקה עם מחיצות חוזרות או בהתקנה מחדש)
מחיצות דינמיות) לא יכולים להשתמש במערכת כשורש. הליבה של Linux לא יכולה
פירוש של המחיצה super
ולכן לא ניתן לטעון
system
עצמו. הטעינה של system
בוצעה עכשיו על ידי
init
שלב ראשון, שנמצא ברדיסק.
לא להגדיר את BOARD_BUILD_SYSTEM_ROOT_IMAGE
. לחשבון
ב-Android 10,
הדגל BOARD_BUILD_SYSTEM_ROOT_IMAGE
משמש רק לצורך
להבחין אם המערכת נטענת על ידי הליבה או באמצעות
שלב ראשון: init
ב-ramdisk.
מתבצעת הגדרה של BOARD_BUILD_SYSTEM_ROOT_IMAGE
לערך true
גורמת לשגיאת build
PRODUCT_USE_DYNAMIC_PARTITIONS
הוא גם true
.
כשהערך של BOARD_USES_RECOVERY_AS_BOOT
מוגדר כ-True, הפונקציה
קובץ האימג' לשחזור בנוי כ-אתחול.img, ומכיל את
Ramdisk. בעבר, תוכנת האתחול השתמשה בליבה (kernel) של skip_initramfs
פרמטר של שורת הפקודה כדי להחליט באיזה מצב לבצע הפעלה. עבור
מכשירי Android 10, אסור לתוכנת האתחול לעבור
skip_initramfs
לשורת הפקודה בליבה (kernel). במקום זאת, תוכנת אתחול
צריך לעבור את androidboot.force_normal_boot=1
כדי לדלג על שלב השחזור
ומפעילים את מכשיר Android הרגיל. מכשירים שמושקים עם Android 12
ואילך, חייבים להשתמש ב-אתחול תצורה כדי להעביר את androidboot.force_normal_boot=1
.
שינויים בהגדרות של AVB
בזמן השימוש ב-Android הפעלה מאומתת 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
footer בסוף 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: שלח שאילתה על GUID של מחיצות בלבד כאשר ה-cmdline זקוק ".
- 5abd6bc2578968d24406d834471adfd995a0c2e9 – 'אפשר להשאיר את מחיצת המערכת חסרה'
- 9ba3b6613b4e5130fa01a11d984c6b5f0eb3af05 – "תיקון AvbSlotVerifyData->cmdline עשוי להיות NULL"
אם משתמשים במחיצות בשרשרת, צריך להוסיף תיקון נוסף:
- 49936b4c0109411fdd38bd4ba3a32a01c40439a9 — libavb: Support vbmeta blobs בתחילת חלוקה."
שינויים בשורת הפקודה בליבה (Kernel)
יש להוסיף פרמטר חדש, androidboot.boot_devices
לשורת הפקודה של הליבה. משמש את init
כדי:
הפעלת קישורים סימבוליים של /dev/block/by-name
. הוא צריך להיות
רכיב הנתיב של המכשיר לקישור הסמלי לפי שם שנוצר על ידי
ueventd
, כלומר
/dev/block/platform/device-path/by-name/partition-name
.
מכשירים שמותקנת בהם מערכת ההפעלה Android בגרסה 12 ואילך חייבים להשתמש ב-
הגדרת האתחול כדי להעביר את androidboot.boot_devices
אל init
.
לדוגמה, אם הקישור הסמלי של מחיצת-על לפי שם הוא
/dev/block/platform/soc/100000.ufshc/by-name/super
,
אפשר להוסיף את פרמטר שורת הפקודה לקובץ BoardConfig.mk בתור
ככה:
BOARD_KERNEL_CMDLINE += androidboot.boot_devices=soc/100000.ufshcאפשר להוסיף את הפרמטר verificationconfig לקובץ BoardConfig.mk באופן הבא:
BOARD_BOOTCONFIG += androidboot.boot_devices=soc/100000.ufshc
שינויים ב-fstab
שכבות-העל של עץ המכשיר ועץ המכשיר לא יכולות להכיל fstab רשומות. משתמשים בקובץ fstab שיהיה חלק מ-ramdisk.
צריך לבצע שינויים בקובץ fstab למחיצות לוגיות:
-
שדה הדגלים fs_mgr חייב לכלול את הדגל
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
אתחול מהיר
תוכנת האתחול (או כל כלי מהבהב שלא כולל מרחב משתמשים) לא מבין מחיצות דינמיות, כך שהוא לא יכול להבהב אותן. כדי לפתור את הבעיה, מכשירים חייב להשתמש ביישום של פרוטוקול אתחול מהיר (fastboot) במרחב המשתמש, שנקרא אתחול מהיר (fastbootd).
מידע נוסף על אופן הטמעת התכונהfastbootd זמין במאמר העברת Fastboot to User Space.
טעינה מחדש של adb
למפתחים שמשתמשים בגרסאות build של AI או ניפוי באגים שקשורים למשתמשים: adb remount
שימושי מאוד לאיטרציה מהירה. מחיצות דינמיות יוצרות
בעיה עבור adb remount
כי כבר אין בחינם
את השטח בתוך כל מערכת קבצים. כדי לפתור את הבעיה, המכשירים יכולים להפעיל
שכבת-על. כל עוד יש מקום פנוי בתוך מחיצת-העל,
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_partitionIMAGE_PARTITION_SIZE
בלוח קיים הגדרות אישיות. - ביטול ההגדרה של
BOARD_partitionIMAGE_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
) שניתן להבהב ישירות
מחיצה. הוא מקבץ אוטומטית את התוכן של
מחיצות, כלומר הוא מכיל system.img
,
vendor.img
וכן הלאה, בנוסף ל-super
מטא-נתונים של מחיצות. את התמונה הזו אפשר לשדרג ישירות
מחיצת super
ללא כלים נוספים או ללא שימוש
אתחול מהיר (fastbootd). אחרי ה-build, super.img
ימוקם ב
${ANDROID_PRODUCT_OUT}
.
עבור מכשירי A/B שמופעלים עם מחיצות דינמיות,
super.img
מכיל תמונות במשבצת A. לאחר ההבהוב של
תמונת-על באופן ישיר, צריך לסמן את חריץ A כזמין לאתחול לפני הפעלה מחדש של
במכשיר.
למכשירי תיקון, make dist
יוצר קבוצה של
super_*.img
תמונות שניתן לשדרג ישירות אליהן
המחיצות הפיזיות המתאימות. לדוגמה, make dist
.
יוצר את super_system.img
ואת super_vendor.img
כאשר BOARD_SUPER_PARTITION_BLOCK_DEVICES
הוא המערכת
ספק. התמונות האלה ממוקמות בתיקיית OTA ב-
target_files.zip
כוונון של מכשיר מיפוי המכשיר
החלוקה הדינמית למחיצות (partitioning) מספקת מענה למספר כלים לא דטרמיניסטיים של מיפוי מכשירים אובייקטים. ייתכן שלא כולן ייווצרו כמצופה, ולכן עליכם לעקוב אחר כל טוענים ומעדכנים את מאפייני 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
אחרי שעיבוד הפקודות יתחיל בשלב init
, הפונקציה
הערך epoll loop
הופך לפעיל והערכים מתחילים להתעדכן. אבל, לפעמים
מאחר שהטריגרים של נכסים לא פעילים עד סוף init
, הם
לא ניתנות לשימוש בשלבי האתחול הראשוניים כדי לטפל ב-root
,
system
או vendor
. אפשר לצפות ל
ברירת המחדל של הליבה 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}