הרכבת מחיצות מוקדם

התקנים התומכים בטרבל חייבים לאפשר הרכבה בשלב ראשון כדי לוודא ש- init יכול לטעון קטעי מדיניות של Linux משופרת אבטחה (SELinux) המפוזרים על פני מחיצות system vendor . גישה זו גם מאפשרת טעינת מודולי ליבה בהקדם האפשרי לאחר אתחול ליבה.

כדי לבצע הרכבה מוקדמת, לאנדרואיד חייבת להיות גישה למערכות הקבצים שבהן המודולים נמצאים. אנדרואיד 8.0 ומעלה תומך בהרכבה /system , /vendor , או /odm כבר בשלב הראשון של זה (כלומר, לפני init SElinux).

ערכי Fstab

באנדרואיד 9 ומטה, מכשירים יכולים לציין ערכי fstab עבור מחיצות מותקנות מוקדם באמצעות שכבות עץ של מכשירים (DTOs) . ב-Android 10 ומעלה, התקנים חייבים לציין ערכי fstab עבור מחיצות מותקנות באמצעות קובץ fstab בשלב הראשון ramdisk . אנדרואיד 10 מציגה את דגלי fs_mgr הבאים לשימוש בקובץ fstab :

  • first_stage_mount מציין שמחיצה תועלה על ידי init השלב הראשון.
  • logical מציין שזו מחיצה דינמית .
  • avb= vbmeta-partition-name מציין את מחיצת vbmeta . השלב הראשון init מאתחל מחיצה זו לפני הרכבה של מחיצות אחרות. ניתן להשמיט את הארגומנט עבור הדגל הזה אם מחיצת 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 לרשימת המחיצות.

מכשירים עם אנדרואיד 10 ומעלה חייבים למקם את קובץ fstab ב-ramdisk ובמחיצת vendor .

רמדיסק

מיקום קובץ fstab ב-ramdisk תלוי באופן שבו התקן משתמש ב-ramdisk.

התקנים עם Ramdisk אתחול חייבים למקם את קובץ fstab בשורש האתחול של Ramdisk. אם להתקן יש גם רמדיסק אתחול וגם רמדיסק לשחזור, לא נדרשים שינויים ב-ramdisk לשחזור. דוגמא:

PRODUCT_COPY_FILES +=  device/google/<product-name>/fstab.hardware:$(TARGET_COPY_OUT_RAMDISK)/fstab.$(PRODUCT_PLATFORM)

התקנים המשתמשים בשחזור כ-ramdisk חייבים להשתמש בפרמטר שורת הפקודה של הליבה androidboot.force_normal_boot=1 כדי להחליט אם לאתחל לאנדרואיד או להמשיך לאתחל לשחזור. מכשירים המופעלים עם אנדרואיד 12 ומעלה עם גרסת ליבה 5.10 ואילך חייבים להשתמש ב-bootconfig כדי להעביר את הפרמטר androidboot.force_normal_boot=1 . בהתקנים אלה, השלב הראשון init עושה פעולת בסיס מתג ל- /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 . הסיבה לכך היא שהשלב הראשון init משחרר את ה-ramdisk לאחר שהוא משלים את ההרכבה המוקדמת של המחיצות ומבצע פעולת בסיס מתג כדי להעביר את ה-mount ב- /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 כוללות:

  1. נתיבים של צומת מכשיר חייבים להשתמש בקישורי by-name שלהם ב- fstab ו- devicetree. לדוגמה, במקום לציין מחיצות באמצעות /dev/block/mmcblk0pX , ודא שלמחיצות יש שם וצומת המכשיר הוא /dev/block/…./by-name/{system,vendor,odm} .
  2. נתיבים שניתנו עבור 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
    
  3. אסור לחזור על ערכים המסופקים באמצעות שכבות על של עץ המכשירים בקטעי קובץ fstab . לדוגמה, כאשר מציינים ערך לטעינה /vendor בעץ המכשיר, אסור לקובץ fstab לחזור על הערך הזה.
  4. אין להרכיב מחיצות הדורשות verifyatboot מוקדם (אין תמיכה בכך).
  5. יש לציין את מצב/מצב האימות עבור מחיצות מאומתות ב- 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 חייבת להיות הרשימה המופרדת בפסיקים של דגלי mount (כמו בקבצי fstab )
    • fsmgr_flags חייבת להיות הרשימה של fs_mgr flags של Android (כמו בקבצי fstab )
  • למחיצות A/B חייבת להיות אפשרות slotselect fs_mgr .
  • למחיצות התומכות ב-dm-verity חייבת להיות אפשרות verify fs_mgr .

דוגמה: /system ו-/ספק ב-N6P

הדוגמה הבאה מציגה התקנה מוקדמת של devicetree עבור מחיצות 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";
        };
      };
    };
  };
};

דוגמה: /ספק ב-Pixel

הדוגמה הבאה מציגה התקנה מוקדמת של devicetree עבור /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 Verified Boot (AVB) . הדרישות להרכבה מוקדמת של מחיצות עם VBoot 2.0 הן:

  1. הנתיבים של צומת ההתקן חייבים להשתמש בקישורי by-name שלהם ב- fstab ו- devicetree. לדוגמה, במקום לציין מחיצות באמצעות /dev/block/mmcblk0pX , ודא שלמחיצות יש שמות וצומת המכשיר הוא /dev/block/…./by-name/{system,vendor,odm} .
  2. בניית משתני מערכת (כגון PRODUCT_{SYSTEM,VENDOR}_VERITY_PARTITION ו- CUSTOM_IMAGE_VERITY_BLOCK_DEVICE ) המשמשים עבור VBoot 1.0 אינם נדרשים עבור VBoot 2.0. במקום זאת, יש להגדיר משתני בנייה שהוצגו ב-VBoot 2.0 (כולל BOARD_AVB_ENABLE := true ); לקבלת תצורה מלאה, עיין ב- Build System Integration for AVB .
  3. אסור לחזור על ערכים המסופקים באמצעות שכבות על של עץ המכשירים בקטעי קובץ fstab . לדוגמה, אם אתה מציין ערך לטעינה /vendor בעץ המכשיר, אסור לקובץ fstab לחזור על הערך הזה.
  4. VBoot 2.0 אינו תומך verifyatboot , בין אם הפעלה מוקדמת מופעלת או לא.
  5. יש לציין את מצב/מצב האימות עבור מחיצות מאומתות ב- 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";
            };
          };
        };
      };
    };
    

דוגמה: /ספק ב-Pixel

הדוגמה הבאה מציגה הרכבה /vendor מוקדם על פיקסל. ציין זאת:

  • מחיצות נוספות מצוינות בערך 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";
            };
          };
        };
      };
    };