การติดตั้งพาร์ติชั่นก่อนเวลา

อุปกรณ์ที่เปิดใช้งาน Treble ต้องเปิดใช้งานการเมานต์ขั้นแรกเพื่อให้แน่ใจว่า init สามารถโหลดส่วนย่อยของนโยบาย Security-Enhanced Linux (SELinux) ที่กระจายไปทั่วพาร์ติชัน system และ vendor การเข้าถึงนี้ยังช่วยให้สามารถโหลดโมดูลเคอร์เนลได้โดยเร็วที่สุดหลังจากการบูตเคอร์เนล

หากต้องการติดตั้งก่อนกำหนด Android จะต้องมีสิทธิ์เข้าถึงระบบไฟล์ที่มีโมดูลอยู่ Android 8.0 และสูงกว่ารองรับการติดตั้ง /system , /vendor หรือ /odm เร็วที่สุดเท่าที่ init ระยะแรก (นั่นคือก่อนที่ SElinux จะเริ่มต้น)

รายการ Fstab

ใน Android 9 และต่ำกว่า อุปกรณ์สามารถระบุรายการ fstab สำหรับพาร์ติชั่นที่เมาท์ก่อนหน้าได้โดยใช้ Device Tree Overlays (DTO) ใน Android 10 ขึ้นไป อุปกรณ์จะต้องระบุรายการ fstab สำหรับพาร์ติชั่นที่เมาท์ก่อนหน้านี้โดยใช้ไฟล์ fstab ใน ramdisk สเตจแรก Android 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 ลงในรายการพาร์ติชันแล้ว

อุปกรณ์ที่ใช้ Android 10 ขึ้นไปจะต้องวางไฟล์ fstab ไว้ใน ramdisk และในพาร์ติชัน vendor

แรมดิสก์

ตำแหน่งไฟล์ fstab ใน ramdisk ขึ้นอยู่กับวิธีที่อุปกรณ์ใช้ ramdisk

อุปกรณ์ ที่มี ramdisk สำหรับบูต จะต้องวางไฟล์ fstab ไว้ในรูทของ ramdisk สำหรับบูต หากอุปกรณ์มีทั้ง ramdisk สำหรับบูตและ ramdisk สำหรับการกู้คืน ก็ไม่จำเป็นต้องทำการเปลี่ยนแปลงกับ ramdisk สำหรับการกู้คืน ตัวอย่าง:

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

อุปกรณ์ ที่ใช้การกู้คืนเป็น ramdisk ต้องใช้พารามิเตอร์บรรทัดคำสั่งเคอร์เนล androidboot.force_normal_boot=1 เพื่อตัดสินใจว่าจะบูตเข้าสู่ Android หรือบูตเข้าสู่การกู้คืนต่อไป อุปกรณ์ที่เปิดตัวด้วย Android 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 หลังจากที่ทำการติดตั้งพาร์ติชันในช่วงแรกเสร็จสิ้นและดำเนินการสวิตช์รูทเพื่อย้ายการเมานต์ที่ /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 และแผนผังอุปกรณ์ ตัวอย่างเช่น แทนที่จะระบุพาร์ติชันโดยใช้ /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 ใน devicetree ไฟล์ fstab จะต้องไม่ทำซ้ำรายการนั้น
  4. พาร์ติชันที่ต้องมี verifyatboot จะต้องไม่ ติดตั้งก่อน (ไม่รองรับการดำเนินการดังกล่าว)
  5. ต้องระบุโหมด/สถานะความจริงสำหรับพาร์ติชันที่ตรวจสอบแล้วใน kernel_cmdline โดยใช้ตัวเลือก androidboot.veritymode (ข้อกำหนดที่มีอยู่)

การติดตั้งทรีอุปกรณ์ตั้งแต่เนิ่นๆ, VBoot 1.0

ใน Android 8.x และสูงกว่า init จะแยกวิเคราะห์แผนผังอุปกรณ์และสร้างรายการ fstab เพื่อติดตั้งพาร์ติชันตั้งแต่เนิ่นๆ ในช่วงระยะแรก รายการ fstab มีรูปแบบ:

src mnt_point type mnt_flags fs_mgr_flags

คุณสมบัติ Devicetree ถูกกำหนดให้เลียนแบบรูปแบบนั้น:

  • รายการ fstab ต้องอยู่ภายใต้ /firmware/android/fstab ใน devicetree และต้องมีสตริงที่เข้ากันได้ที่ตั้งค่าเป็น 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

ตัวอย่างต่อไปนี้แสดงการติดตั้ง 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";
        };
      };
    };
  };
};

ตัวอย่าง: /vendor บน 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 และแผนผังอุปกรณ์ ตัวอย่างเช่น แทนที่จะระบุพาร์ติชันโดยใช้ /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 ใน devicetree ไฟล์ fstab จะต้องไม่ทำซ้ำรายการนั้น
  4. VBoot 2.0 ไม่รองรับ verifyatboot ไม่ว่าจะเปิดใช้งานการเมานต์ล่วงหน้าหรือไม่ก็ตาม
  5. ต้องระบุโหมด/สถานะความจริงสำหรับพาร์ติชันที่ตรวจสอบแล้วใน kernel_cmdline โดยใช้ตัวเลือก androidboot.veritymode (ข้อกำหนดที่มีอยู่) ตรวจสอบให้แน่ใจว่าได้รวมการแก้ไขต่อไปนี้สำหรับ AVB:

การติดตั้งทรีอุปกรณ์ตั้งแต่เนิ่นๆ, VBoot 2.0

การกำหนดค่าใน devicetree สำหรับ VBoot 2.0 จะเหมือนกับการกำหนดค่าใน VBoot 1.0 โดยมีข้อยกเว้นต่อไปนี้:

  • fsmgr_flag ถูกเปลี่ยนจาก verify เป็น avb
  • พาร์ติชันทั้งหมดที่มีข้อมูลเมตา AVB จะต้องอยู่ในรายการ VBMeta ในแผนผังอุปกรณ์ แม้ว่าพาร์ติชันจะไม่ได้ติดตั้งเร็วก็ตาม (เช่น /boot )

ตัวอย่าง: /system และ /vendor บน N5X

ตัวอย่างต่อไปนี้แสดงการติดตั้ง Devicetree ก่อนสำหรับ 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";
            };
          };
        };
      };
    };