ต่อเชื่อมพาร์ติชันล่วงหน้า

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

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

รายการ Fstab

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

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

แรมดิสค์

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

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

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

อุปกรณ์ที่ใช้การกู้คืนเป็น RAM ต้องใช้ พารามิเตอร์บรรทัดคำสั่งของเคอร์เนล androidboot.force_normal_boot=1 ไปยัง ตัดสินใจว่าจะเปิดเครื่องใน Android หรือเปิดเครื่องในการกู้คืน อุปกรณ์ การเปิดตัวด้วย Android 12 ขึ้นไปพร้อมด้วย เคอร์เนลเวอร์ชัน 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 นั่นเป็นเพราะขั้นตอนแรกทำให้ 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 และรายการ 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 ต้องเป็นรายการเมาท์แฟล็กที่คั่นด้วยจุลภาค (เช่น fstab ไฟล์)
    • fsmgr_flags ต้องเป็นรายการ Android fs_mgr flags (ดังในไฟล์ 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 ได้แก่

  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) ควรได้รับการกำหนด สำหรับ การกำหนดค่าทั้งหมด โปรดดู สร้างการผสานรวมระบบสำหรับ 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 ในข้อมูลโค้ด devicetree แม้ว่าพาร์ติชันจะยังไม่ได้ต่อเชื่อมก่อนหน้านี้ก็ตาม (ตัวอย่างเช่น /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";
            };
          };
        };
      };
    };