במכשירים שתומכים ב-Treble, חייבים להפעיל טעינה בשלב הראשון כדי לוודא
הספק init
יכול לטעון את Linux עם שיפור אבטחה
(SELinux) קטעי מדיניות שמפוזרים על פני system
ו-
vendor
מחיצות. הגישה הזו מאפשרת גם לטעון ליבה (kernel)
בהקדם האפשרי אחרי אתחול הליבה.
כדי לבצע טעינה מוקדמת, ל-Android צריכה להיות גישה למערכות הקבצים ב-
שבהם נמצאים המודולים. Android מגרסה 8.0 ואילך תומכת בטעינה
/system
, /vendor
או /odm
כבר עכשיו
השלב הראשון של init
(כלומר, לפני אתחול SElinux).
רשומות Fstab
ב-Android מגרסה 9 ומטה, אפשר לציין במכשירים fstab
רשומות עבור
מחיצות שהותקנו מראש באמצעות עץ המכשירים
שכבות-על (DTO). ב-Android מגרסה 10 ואילך,
המכשירים חייבים לציין fstab
רשומות למחיצות שנטענו מוקדם
באמצעות קובץ fstab
בשלב הראשון
ramdisk. במכשירי Android
10 מציג את הדגלים הבאים של fs_mgr
לשימוש בקובץ fstab
:
first_stage_mount
מציין שקיימת מחיצה של השלב הראשון.logical
מציין חלוקה דינמית.avb=vbmeta-partition-name
מציין את הערך מחיצהvbmeta
. השלב הראשון מאתחל את המחיצה לפני התקנת מחיצות אחרות. אפשר להשמיט את הארגומנט של הדגל הזה אם המחיצהvbmeta
עבור הרשומה כבר צוינה על ידי רשומתfstab
נוספת בשורה הקודמת.
הדוגמה הבאה מציגה רשומות של fstab
כדי להגדיר את
system
, vendor
ו-product
מחיצות
כמחיצות לוגיות (דינמיות).
#<dev> <mnt_point> <type> <mnt_flags options> <fs_mgr_flags> system /system ext4 ro,barrier=1 wait,slotselect,avb=vbmeta_system,logical,first_stage_mount vendor /vendor ext4 ro,barrier=1 wait,slotselect,avb=vbmeta,logical,first_stage_mount product /product ext4 ro,barrier=1 wait,slotselect,avb,logical,first_stage_mount
בדוגמה זו, הספק מציין את המחיצה vbmeta
באמצעות
הדגל fs_mgr
avb=vbmeta
, אבל product
משמט את הארגומנט vbmeta
כי הספק כבר הוסיף
vbmeta
לרשימת המחיצות.
במכשירים עם Android מגרסה 10 ואילך חייבים להציב את
קובץ fstab
ב-ramdisk וב-vendor
מחיצה.
רמדיסק
המיקום של קובץ fstab
ב-ramdisk תלוי באופן שבו המכשיר
משתמש ב-ramdisk.
מכשירים עם רדיסק אתחול חייבים להציב את השדה fstab
בתיקיית השורש של RAMdisk האתחול. אם למכשיר יש גם רדיסק אתחול וגם
ramdisk שחזור, לא נדרשים שינויים ברדיסק השחזור. דוגמה:
PRODUCT_COPY_FILES += device/google/<product-name>/fstab.hardware:$(TARGET_COPY_OUT_RAMDISK)/fstab.$(PRODUCT_PLATFORM)
מכשירים שמשתמשים בהם כ-Radisk חייבים להשתמש
פרמטר שורת הפקודה androidboot.force_normal_boot=1
של הליבה ל-
ולהחליט אם לבצע אתחול ב-Android או להמשיך בתהליך השחזור. מכשירים
השקה עם Android מגרסה 12 ואילך עם
גרסת ליבה (kernel) 5.10 ואילך חייבת להשתמש ב-bootconfig כדי להעביר את
הפרמטר androidboot.force_normal_boot=1
. לחשבון
במכשירים האלה, השלב הראשון מבצע פעולת שורש של החלפה
/first_stage_ramdisk
לפני טעינת מחיצות הטעינה המוקדמות,
לכן המכשירים חייבים למקם את הקובץ fstab
$(TARGET_COPY_OUT_RECOVERY)/root/first_stage_ramdisk
. דוגמה:
PRODUCT_COPY_FILES += device/google/<product-name>/fstab.hardware:$(TARGET_COPY_OUT_RECOVERY)/root/first_stage_ramdisk/fstab.$(PRODUCT_PLATFORM)
ספק
בכל המכשירים צריך להעביר עותק של הקובץ fstab
אל
/vendor/etc
. הסיבה לכך היא שהשלב הראשון משחרר
אחרי שהיא מסיימת את ההתקנה המוקדמת של המחיצות ומבצעת
החלפת פעולת הבסיס כדי להעביר את הטעינה ב-/system
אל
/
. כל הפעולות הבאות שנדרשות כדי לגשת אל fstab
לכן חייבים להשתמש בעותק שבקובץ /vendor/etc
. דוגמה:
PRODUCT_COPY_FILES += device/google/<product-name>/fstab.hardware:$(TARGET_COPY_OUT_VENDOR)/etc/fstab.$(PRODUCT_PLATFORM)
טעינת מחיצות בשלב מוקדם, VBoot 1.0
הדרישות לטעינה מוקדמת של מחיצות באמצעות VBoot 1.0 כוללות:
- נתיבי צמתים של מכשירים חייבים להשתמש בסמלי ה-
by-name
שלהם ב- רשומותfstab
ועץ המכשיר. לדוגמה, במקום לציין מחיצות באמצעות/dev/block/mmcblk0pX
, צריך לוודא שהמחיצות שם, וצומת המכשיר הוא/dev/block/…./by-name/{system,vendor,odm}
. - נתיבים שניתנו עבור
PRODUCT_{SYSTEM,VENDOR}_VERITY_PARTITION
וCUSTOM_IMAGE_VERITY_BLOCK_DEVICE
בהגדרת המכשיר של את המוצר (כלומרdevice/oem/project/device.mk
) חייב להתאים הצמתים התואמים של המכשירים החסומים שצוינוby-name
רשומותfstab
/devicetree. דוגמה:PRODUCT_SYSTEM_VERITY_PARTITION := /dev/block/…./by-name/system PRODUCT_VENDOR_VERITY_PARTITION := /dev/block/…./by-name/vendor CUSTOM_IMAGE_VERITY_BLOCK_DEVICE := /dev/block/…./by-name/odm
- אסור שרשומות שסופקו באמצעות שכבות-על של עץ מכשירים לא יחזרו על עצמן
fstab
מקטעים של קובץ. לדוגמה, כשמציינים ערך של צריך לטעון את/vendor
לעץ המכשיר, הקובץfstab
אסור לחזור על הרשומה הזו. - אסור למחיצות שנדרשת בהן
verifyatboot
לבצע טעינה מוקדמת (הפעולה הזו לא נתמכת). - יש לציין את מצב/מצב האימות של מחיצות מאומתות ב-
kernel_cmdline
עם אפשרות אחת (androidboot.veritymode
) (דרישה קיימת).
התקנת devicetree מוקדמת, VBoot 1.0
ב-Android מגרסה 8.x ואילך, init
מנתח את עץ המכשיר ו
יוצרת רשומות fstab
כדי לטעון את המחיצה מוקדם במהלך
השלב הראשון. רשומת fstab
תופיע בטופס:
src mnt_point type mnt_flags fs_mgr_flags
מאפייני Devicetree מוגדרים כך שמחקים את הפורמט הזה:
fstab
רשומות חייבות להיות מתחת/firmware/android/fstab
בעץ המכשיר וחייבת להיות לו המחרוזת התואמת שהוגדרה היאandroid,fstab
.- כל צומת בערך
/firmware/android/fstab
נחשב ערך אחד של טעינה מוקדמת שלfstab
. צומת צריך לכלול: מאפיינים מוגדרים:dev
חייב להצביע על הצומת של המכשיר שמייצג את מחיצהby-name
type
חייב להיות סוג מערכת הקבצים (כמוfstab
קבצים)mnt_flags
חייב להיות רשימה מופרדת בפסיקים של דגלי טעינה (כמו ב-fstab
קבצים)fsmgr_flags
חייבת להיות הרשימה שלfs_mgr flags
ב-Android (כמו ב-fstab
קבצים)
- למחיצות A/B חייבת להיות אפשרות
slotselect fs_mgr
. - מחיצות שמופעלות ב-dm-verity חייבות לכלול
verify fs_mgr
כאפשרות.
דוגמה: /system ו /vendor ב-N6P
בדוגמה הבאה מוצגת טעינה מוקדמת של עץ המכשיר עבור system
ו-vendor
מחיצות ב-Nexus 6P:
/ { firmware { android { compatible = "android,firmware"; fstab { compatible = "android,fstab"; system { compatible = "android,system"; dev = "/dev/block/platform/soc.0/f9824900.sdhci/by-name/system"; type = "ext4"; mnt_flags = "ro,barrier=1,inode_readahead_blks=8"; fsmgr_flags = "wait,verify"; }; vendor { compatible = "android,vendor"; dev = "/dev/block/platform/soc.0/f9824900.sdhci/by-name/vendor"; type = "ext4"; mnt_flags = "ro,barrier=1,inode_readahead_blks=8"; fsmgr_flags = "wait"; }; }; }; }; };
לדוגמה: /vendor ב-Pixel
בדוגמה הבאה מוצגת טעינה מוקדמת של עץ המכשיר עבור /vendor
ב-Pixel (חשוב לזכור להוסיף את slotselect
למחיצות שכפופה
A/B):
/ { firmware { android { compatible = "android,firmware"; fstab { compatible = "android,fstab"; vendor { compatible = "android,vendor"; dev = "/dev/block/platform/soc/624000.ufshc/by-name/vendor"; type = "ext4"; mnt_flags = "ro,barrier=1,discard"; fsmgr_flags = "wait,slotselect,verify"; }; }; }; }; };
טעינת מחיצות בשלב מוקדם, VBoot 2.0
VBoot 2.0 הוא אתחול מאומת של Android (AVB). הדרישות להשתתפות בתוכנית מחיצות טעינה עם VBoot 2.0 הן:
- נתיבי הצמתים של המכשיר חייבים להשתמש בסמלי הסימלין של
by-name
שלהם ב- רשומותfstab
ועץ המכשיר. לדוגמה, במקום לציין מחיצות באמצעות/dev/block/mmcblk0pX
, צריך לוודא שהמחיצות מופיעים שמות, וצומת המכשיר הוא/dev/block/…./by-name/{system,vendor,odm}
. - לבנות משתני מערכת (כמו
PRODUCT_{SYSTEM,VENDOR}_VERITY_PARTITION
והקבוצהCUSTOM_IMAGE_VERITY_BLOCK_DEVICE
) משמש עבור VBoot 1.0 אינם נדרש ל-VBoot 2.0. במקום זאת, כדאי לבנות משתנים שהוכנסו ל-VBoot 2.0. צריך להגדיר (כוללBOARD_AVB_ENABLE := true
). עבור הגדרות אישיות מלאות, יצירת שילוב מערכת ל-AVB. - אסור שרשומות שסופקו באמצעות שכבות-על של עץ מכשירים לא יחזרו על עצמן
fstab
מקטעים של קובץ. לדוגמה, אם תציינו ערך עבור צריך לטעון את/vendor
לעץ המכשיר, הקובץfstab
אסור לחזור על הרשומה הזו. - ב-VBoot 2.0 אין תמיכה ב-
verifyatboot
, גם אם בטעינה מוקדמת מופעלת או לא מופעלת. - יש לציין את מצב/מצב האימות של מחיצות מאומתות ב-
kernel_cmdline
באמצעותandroidboot.veritymode
אפשרות (דרישה קיימת). חשוב לכלול את התיקונים הבאים לגבי AVB:
התקנת devicetree מוקדמת, VBoot 2.0
ההגדרה ב-devicetree של VBoot 2.0 זהה לזו שב- VBoot 1.0, עם התג החריגים הבאים:
- הערך בעמודה
fsmgr_flag
השתנה מ-verify
ל-avb
. - כל המחיצות עם מטא-נתונים של AVB חייבות להיות ברשומת VBMeta
מכשיר, גם אם המחיצה לא נטענת מוקדם (לדוגמה,
/boot
).
דוגמה: /system ו /vendor ב-N5X
בדוגמה הבאה מוצגת טעינה מוקדמת של עץ המכשיר עבור
מחיצות system
ו-vendor
ב-Nexus 5X. הערה:
/system
נטען עם AVB ו-/vendor
הוא טעונה ללא אימות תקינות.- ב-Nexus 5X אין מחיצת
/vbmeta
, לכן ברמה העליונה vbmeta נמצאת בסוף המחיצה/boot
(לפרטים, תוכלו למצוא מידע נוסף ברשימת השינויים של AOSP)./ { firmware { android { compatible = "android,firmware"; vbmeta { compatible = "android,vbmeta"; parts = "boot,system,vendor"; }; fstab { compatible = "android,fstab"; system { compatible = "android,system"; dev = "/dev/block/platform/soc.0/f9824900.sdhci/by-name/system"; type = "ext4"; mnt_flags = "ro,barrier=1,inode_readahead_blks=8"; fsmgr_flags = "wait,avb"; }; vendor { compatible = "android,vendor"; dev = "/dev/block/platform/soc.0/f9824900.sdhci/by-name/vendor"; type = "ext4"; mnt_flags = "ro,barrier=1,inode_readahead_blks=8"; fsmgr_flags = "wait"; }; }; }; }; };
לדוגמה: /vendor ב-Pixel
בדוגמה הבאה רואים טעינה של /vendor
בשלב מוקדם של Pixel.
הערה:
- מחיצות נוספות מפורטות ברשומת vbmeta מכיוון שהמחיצות האלה הן מוגנות באמצעות AVB.
- צריך לכלול את כל מחיצות ה-AVB, גם אם רק
/vendor
עם טעינה מוקדמת. - חשוב לזכור להוסיף את
slotselect
למחיצות שכפופים ל-A/B./ { vbmeta { compatible = "android,vbmeta"; parts = "vbmeta,boot,system,vendor,dtbo"; }; firmware { android { compatible = "android,firmware"; fstab { compatible = "android,fstab"; vendor { compatible = "android,vendor"; dev = "/dev/block/platform/soc/624000.ufshc/by-name/vendor"; type = "ext4"; mnt_flags = "ro,barrier=1,discard"; fsmgr_flags = "wait,slotselect,avb"; }; }; }; }; };