เค้าโครงพาร์ทิชัน

ใน Android 10 ระบบไฟล์รูทจะไม่รวมอยู่ใน ramdisk.img อีกต่อไป และจะรวมเข้ากับ system.img แทน (นั่นคือ system.img จะถูกสร้างขึ้นเสมอเหมือนกับว่า BOARD_BUILD_SYSTEM_ROOT_IMAGE ถูกตั้งค่าไว้) อุปกรณ์ที่เปิดตัวพร้อม Android 10:

  • ใช้โครงร่างพาร์ติชันระบบในฐานะรูท (บังคับใช้โดยอัตโนมัติโดยบิลด์โดยไม่มีตัวเลือกในการเปลี่ยนแปลงลักษณะการทำงาน)
  • ต้องใช้ ramdisk ซึ่งจำเป็นสำหรับ dm-linear
  • ต้องตั้งค่า BOARD_BUILD_SYSTEM_ROOT_IMAGE เป็น false การตั้งค่านี้ใช้เพื่อแยกความแตกต่างระหว่างอุปกรณ์ที่ใช้ ramdisk และอุปกรณ์ที่ไม่ใช้ ramdisk เท่านั้น (และเมาท์ system.img โดยตรงแทน)

ความหมายของการกำหนดค่าระบบในฐานะรูทจะแตกต่างกันระหว่าง Android 9 และ Android 10 ในการกำหนดค่าระบบในฐานะรูทของ Android 9 BOARD_BUILD_SYSTEM_ROOT_IMAGE จะถูกตั้งค่าเป็น true ซึ่งบังคับให้บิลด์รวมระบบไฟล์รูทเข้ากับ system.img จากนั้น เมานต์ system.img เป็นระบบไฟล์รูท (rootfs) การกำหนดค่านี้ จำเป็น สำหรับอุปกรณ์ที่เปิดตัวด้วย Android 9 แต่เป็น ทางเลือก สำหรับอุปกรณ์ที่อัปเกรดเป็น Android 9 และสำหรับอุปกรณ์ที่ใช้ Android เวอร์ชันต่ำกว่า ในการกำหนดค่าระบบในฐานะรูทของ Android 10 บิลด์จะรวม $TARGET_SYSTEM_OUT และ $TARGET_ROOT_OUT เข้ากับ system.img เสมอ การกำหนดค่านี้เป็นพฤติกรรมเริ่มต้นสำหรับอุปกรณ์ทั้งหมดที่ใช้ Android 10

Android 10 ทำการเปลี่ยนแปลงเพิ่มเติมเพื่อรองรับ พาร์ติชันแบบไดนามิก ซึ่งเป็นระบบการแบ่งพาร์ติชันพื้นที่ผู้ใช้ที่เปิดใช้งานการอัปเดตแบบ over-the-air (OTA) เพื่อสร้าง ปรับขนาด หรือทำลายพาร์ติชัน ส่วนหนึ่งของการเปลี่ยนแปลงนี้ เคอร์เนล Linux ไม่สามารถเมานต์พาร์ติชันระบบแบบลอจิคัลบนอุปกรณ์ที่ใช้ Android 10 ได้อีกต่อไป ดังนั้นการดำเนินการนี้จะได้รับการจัดการโดย init ระยะแรก

ส่วนต่อไปนี้จะอธิบายข้อกำหนดของระบบในฐานะรูทสำหรับ OTA เฉพาะระบบ ให้คำแนะนำในการอัปเดตอุปกรณ์เพื่อใช้ระบบในฐานะรูท (รวมถึงการเปลี่ยนแปลงเค้าโครงพาร์ติชันและข้อกำหนดเคอร์เนล dm-verity) สำหรับรายละเอียดเกี่ยวกับการเปลี่ยนแปลง ramdisk โปรดดูที่ Ramdisk Partitions

เกี่ยวกับ OTA เฉพาะระบบ

OTA เฉพาะระบบ ซึ่งช่วยให้ Android รุ่นต่างๆ สามารถอัปเดต system.img และ product.img โดยไม่ต้องเปลี่ยนพาร์ติชั่นอื่นๆ จำเป็นต้องมีโครงร่างพาร์ติชั่นระบบเหมือนเป็นรูท อุปกรณ์ทั้งหมดที่ใช้ Android 10 ต้องใช้เค้าโครงพาร์ติชันระบบเป็นรูทเพื่อเปิดใช้งาน OTA เฉพาะระบบ

  • อุปกรณ์ A/B ซึ่งติดตั้งพาร์ติชัน system เป็น rootfs ใช้ระบบเป็น root อยู่แล้ว และไม่จำเป็นต้องมีการเปลี่ยนแปลงเพื่อรองรับ OTA ของระบบ
  • อุปกรณ์ที่ไม่ใช่ A/B ซึ่งติดตั้งพาร์ติชัน system ที่ /system จะต้องได้รับ การอัปเดตเพื่อใช้โครงร่างพาร์ติชันระบบในฐานะรูท เพื่อรองรับ OTA ของระบบ

สำหรับรายละเอียดเกี่ยวกับอุปกรณ์ A/B และที่ไม่ใช่ A/B โปรดดู การอัปเดตระบบ A/B (ไร้รอยต่อ)

การใช้การซ้อนทับของผู้ขาย

การซ้อนทับของผู้จำหน่ายทำให้คุณสามารถโอเวอร์เลย์การเปลี่ยนแปลงไปยังพาร์ติชันของ vendor ณ เวลาบูตอุปกรณ์ได้ โอเวอร์เลย์ของผู้จำหน่ายคือชุดของโมดูลของผู้จำหน่ายในพาร์ติชั่น product ที่ถูกโอเวอร์เลย์บนพาร์ติชั่น vendor เมื่ออุปกรณ์บูท เปลี่ยนและเพิ่มโมดูลที่มีอยู่

เมื่ออุปกรณ์บูท กระบวนการ init จะเสร็จสิ้นการเมานต์ระยะแรกและอ่านคุณสมบัติดีฟอลต์ จากนั้นจะค้นหา /product/vendor_overlay/<target_vendor_version> และเมาท์แต่ละไดเร็กทอรีย่อยบนไดเร็กทอรีพาร์ติชัน vendor ที่เกี่ยวข้อง หากตรงตามเงื่อนไขต่อไปนี้:

  • /vendor/<overlay_dir> มีอยู่
  • /product/vendor_overlay/<target_vendor_version>/<overlay_dir> มีบริบทของไฟล์เหมือนกับ /vendor/<overlay_dir>
  • init ได้รับอนุญาตให้เมานต์บนบริบทไฟล์ของ /vendor/<overlay_dir>

การใช้การซ้อนทับของผู้ขาย

ติดตั้งไฟล์โอเวอร์เลย์ของผู้ขายใน /product/vendor_overlay/<target_vendor_version> ไฟล์เหล่านั้นซ้อนทับพาร์ติชัน vendor เมื่ออุปกรณ์บูท แทนที่ไฟล์ที่มีชื่อเดียวกันและเพิ่มไฟล์ใหม่ การซ้อนทับของผู้จัดจำหน่ายไม่สามารถลบไฟล์ออกจากพาร์ติชัน vendor ได้

ไฟล์ซ้อนทับของผู้จัดจำหน่ายต้องมีบริบทของไฟล์เดียวกันกับไฟล์เป้าหมายที่จะแทนที่ในพาร์ติชัน vendor โดยดีฟอลต์ ไฟล์ในไดเร็กทอรี /product/vendor_overlay/<target_vendor_version> จะมีบริบท vendor_file หากมีบริบทของไฟล์ไม่ตรงกันระหว่างไฟล์ซ้อนทับของผู้ขายและไฟล์ที่แทนที่ ให้ระบุสิ่งนั้นใน sepolicy เฉพาะอุปกรณ์ บริบทของไฟล์ถูกตั้งค่าในระดับไดเร็กทอรี หากบริบทไฟล์ของไดเร็กทอรีโอเวอร์เลย์ของผู้จำหน่ายไม่ตรงกับไดเร็กทอรีเป้าหมาย และไม่ได้ระบุบริบทของไฟล์ที่ถูกต้องใน sepolicy เฉพาะอุปกรณ์ ไดเร็กทอรีโอเวอร์เลย์ของผู้จำหน่ายนั้นจะไม่ซ้อนทับบนไดเร็กทอรีเป้าหมาย

หากต้องการใช้การซ้อนทับของผู้ขาย เคอร์เนลต้องเปิดใช้งาน OverlayFS โดยการตั้งค่า CONFIG_OVERLAY_FS=y นอกจากนี้ เคอร์เนลจะต้องถูกรวมจากเคอร์เนลทั่วไป 4.4 หรือใหม่กว่า หรือมีแพตช์ด้วย "overlayfs: override_creds=off option bypass creator_cred"

ตัวอย่างการใช้งานการซ้อนทับของผู้ขาย

ขั้นตอนนี้สาธิตการใช้งานการซ้อนทับของผู้ขายที่ซ้อนทับไดเร็กทอรี /vendor/lib/* , /vendor/etc/* และ /vendor/app/*

  1. เพิ่มไฟล์ผู้จำหน่ายที่สร้างไว้ล่วงหน้าใน device/<vendor>/<target>/vendor_overlay/<target_vendor_version>/ :

    device/google/device/vendor_overlay/28/lib/libfoo.so
    device/google/device/vendor_overlay/28/lib/libbar.so
    device/google/device/vendor_overlay/28/etc/baz.xml
    device/google/device/vendor_overlay/28/app/qux.apk
    
  2. ติดตั้งไฟล์ผู้จำหน่ายที่สร้างไว้ล่วงหน้าไปที่ product/vendor_overlay ใน device/google/device/device.mk :

    PRODUCT_COPY_FILES += \
        $(call find-copy-subdir-files,*,device/google/device/vendor_overlay,$(TARGET_COPY_OUT_PRODUCT)/vendor_overlay)
    
  3. กำหนดบริบทของไฟล์หากไฟล์พาร์ติชัน vendor เป้าหมายมีบริบทอื่นที่ไม่ใช่ vendor_file เนื่องจาก /vendor/lib/* ใช้บริบท vendor_file ตัวอย่างนี้จึงไม่รวมไดเร็กทอรีนั้น

    เพิ่มสิ่งต่อไปนี้ใน device/google/device-sepolicy/private/file_contexts :

    /(product|system/product)/vendor_overlay/[0-9]+/etc(/.*)?   u:object_r:vendor_configs_file:s0
    /(product|system/product)/vendor_overlay/[0-9]+/app(/.*)?   u:object_r:vendor_app_file:s0
    
  4. อนุญาตให้กระบวนการ init เมานต์โอเวอร์เลย์ของผู้ขายบนบริบทของไฟล์อื่นที่ไม่ใช่ vendor_file เนื่องจากกระบวนการ init มีสิทธิ์ในการติดตั้งบนบริบท vendor_file ตัวอย่างนี้จึงไม่ได้กำหนดนโยบายสำหรับ vendor_file

    เพิ่มสิ่งต่อไปนี้ใน device/google/device-sepolicy/public/init.te :

    allow init vendor_configs_file:dir mounton;
    allow init vendor_app_file:dir mounton;
    

กำลังตรวจสอบการซ้อนทับของผู้ขาย

หากต้องการตรวจสอบการกำหนดค่าการซ้อนทับของผู้ขาย ให้เพิ่มไฟล์ใน /product/vendor_overlay/<target_vendor_version>/<overlay_dir> และตรวจสอบว่าไฟล์ถูกซ้อนทับบนไฟล์ใน /vendor/<overlay_dir> หรือไม่

สำหรับ userdebug builds มีโมดูลทดสอบสำหรับ Atest :

$ atest -v fs_mgr_vendor_overlay_test

กำลังอัปเดตเป็นระบบในฐานะรูท

หากต้องการอัปเดตอุปกรณ์ที่ไม่ใช่ A/B เพื่อใช้ระบบในฐานะรูท คุณต้องอัปเดตรูปแบบการแบ่งพาร์ติชันสำหรับ boot.img และ system.img ตั้งค่า dm-verity และลบการพึ่งพาการบูตใดๆ บนโฟลเดอร์รูทเฉพาะอุปกรณ์

กำลังอัปเดตพาร์ติชัน

ต่างจากอุปกรณ์ A/B ที่ปรับใช้ /boot เป็นพาร์ติชั่ นการกู้คืน อุปกรณ์ที่ไม่ใช่ A/B จะต้องแยกพาร์ติชั่น /recovery ออกจากกัน เนื่องจากไม่มีพาร์ติชั่นสล็อตทางเลือก (เช่น จาก boot_a ถึง boot_b ) หาก /recovery ถูกลบออกจากอุปกรณ์ที่ไม่ใช่ A/B และทำคล้ายกับรูปแบบ A/B โหมดการกู้คืนอาจหยุดทำงานในระหว่างการอัพเดตพาร์ติชั่น /boot ที่ล้มเหลว ด้วยเหตุนี้ พาร์ติ /recovery จะต้อง เป็นพาร์ติชันแยกต่างหากจาก /boot สำหรับอุปกรณ์ที่ไม่ใช่ A/B ซึ่งหมายความว่าอิมเมจการกู้คืนจะได้รับการอัปเดตต่อไปในลักษณะที่เลื่อนออกไป (นั่นคือ เช่นเดียวกับในอุปกรณ์ที่ใช้ Android 8.1.0 หรือต่ำกว่า)

ตารางต่อไปนี้แสดงความแตกต่างของพาร์ติชันรูปภาพสำหรับอุปกรณ์ที่ไม่ใช่ A/B ก่อนและหลัง Android 9

ภาพ แรมดิสก์ (ก่อน 9 โมง) ระบบในฐานะรูท (หลัง 9)
boot.img ประกอบด้วยเคอร์เนลและ ramdisk.img :
ramdisk.img
  -/
    - init.rc
    - init
    - etc -> /system/etc
    - system/ (mount point)
    - vendor/ (mount point)
    - odm/ (mount point)
    ...
มีเคอร์เนลสำหรับบูตปกติเท่านั้น
recovery.img ประกอบด้วยเคอร์เนลการกู้คืนและการกู้คืน ramdisk.img
system.img ประกอบด้วยสิ่งต่อไปนี้:
system.img
  -/
    - bin/
    - etc
    - vendor -> /vendor
    - ...
มีเนื้อหาที่ผสานของ system.img ดั้งเดิมและ ramdisk.img :
system.img
  -/
    - init.rc
    - init
    - etc -> /system/etc
    - system/
      - bin/
      - etc/
      - vendor -> /vendor
      - ...
    - vendor/ (mount point)
    - odm/ (mount point)
    ...

พาร์ติชั่นเองไม่เปลี่ยนแปลง ทั้ง ramdisk และ system-as-root ใช้โครงร่างพาร์ติชันต่อไปนี้:

  • /boot
  • /system
  • /system
  • /recovery
  • /vendor ฯลฯ

การตั้งค่า dm-verity

ใน system-as-root เคอร์เนลจะต้องเมานต์ system.img ภายใต้ / (จุดเมานท์) ด้วย dm-verity AOSP รองรับการใช้งาน dm-verity ต่อไปนี้สำหรับ system.img

วีบูต 1.0

สำหรับ vboot 1.0 เคอร์เนลจะต้องแยกวิเคราะห์ ข้อมูลเมตา เฉพาะของ Android บน /system จากนั้นแปลงเป็น พารามิเตอร์ dm-verity เพื่อตั้งค่า dm-verity (ต้องใช้ แพทช์เคอร์เนลเหล่านี้ ) ตัวอย่างต่อไปนี้แสดงการตั้งค่าที่เกี่ยวข้องกับ dm-verity สำหรับ system-as-root ในบรรทัดคำสั่งเคอร์เนล:

ro root=/dev/dm-0 rootwait skip_initramfs init=/init
dm="system none ro,0 1 android-verity /dev/sda34"
veritykeyid=id:7e4333f9bba00adfe0ede979e28ed1920492b40f

วีบูต 2.0

สำหรับ vboot 2.0 ( AVB ) บูตโหลดเดอร์จะต้องผสานรวม external/avb/libavb ซึ่งจะแยกวิเคราะห์ descriptor hashtree สำหรับ /system แปลงเป็น dm-verity params และสุดท้ายก็ส่งพารามิเตอร์ไปยังเคอร์เนลผ่านบรรทัดคำสั่งเคอร์เนล (ตัวอธิบาย Hashtree ของ /system อาจอยู่บน /vbmeta หรือบน /system เอง)

vboot 2.0 ต้องการแพตช์เคอร์เนลต่อไปนี้:

ตัวอย่างต่อไปนี้แสดงการตั้งค่าที่เกี่ยวข้องกับ dm-verity สำหรับ system-as-root ในบรรทัดคำสั่งเคอร์เนล:

ro root=/dev/dm-0 rootwait  skip_initramfs init=/init

dm="1 vroot none ro 1,0 5159992 verity 1
PARTUUID=00000016-0000-0000-0000-000000000000
PARTUUID=00000016-0000-0000-0000-000000000000 4096 4096 644999 644999
sha1 d80b4a8be3b58a8ab86fad1b498640892d4843a2
8d08feed2f55c418fb63447fec0d32b1b107e42c 10 restart_on_corruption
ignore_zero_blocks use_fec_from_device
PARTUUID=00000016-0000-0000-0000-000000000000 fec_roots 2 fec_blocks
650080 fec_start 650080"

การใช้โฟลเดอร์รูทเฉพาะอุปกรณ์

เมื่อใช้ระบบในฐานะรูท หลังจากที่ อิมเมจระบบทั่วไป (GSI) ถูกแฟลชบนอุปกรณ์ (และก่อนที่จะรันการทดสอบ Vendor Test Suite ) โฟลเดอร์รูทเฉพาะอุปกรณ์ใดๆ ที่เพิ่มด้วย BOARD_ROOT_EXTRA_FOLDERS จะหายไปเนื่องจากเนื้อหาไดเร็กทอรีรูททั้งหมดถูกแทนที่ โดยระบบ-as-root GSI การลบโฟลเดอร์เหล่านี้อาจทำให้อุปกรณ์ไม่สามารถบูตได้หากมีการพึ่งพาโฟลเดอร์รูทเฉพาะอุปกรณ์อยู่ (เช่น ใช้เป็นจุดต่อเชื่อม)

เพื่อหลีกเลี่ยงปัญหานี้ อย่าใช้ BOARD_ROOT_EXTRA_FOLDERS เพื่อเพิ่มโฟลเดอร์รูทเฉพาะอุปกรณ์ หากคุณต้องการระบุจุดเชื่อมต่อเฉพาะอุปกรณ์ ให้ใช้ /mnt/vendor/<mount point> (เพิ่มใน รายการการเปลี่ยนแปลง เหล่านี้) จุดเมานท์เฉพาะผู้จำหน่ายเหล่านี้สามารถระบุได้โดยตรงทั้งในแผนผังอุปกรณ์ fstab (สำหรับการเมานต์ขั้นแรก) และไฟล์ /vendor/etc/fstab.{ro.hardware} โดยไม่ต้องตั้งค่าเพิ่มเติม (เนื่องจาก fs_mgr สร้างขึ้นภายใต้ /mnt/vendor/* อัตโนมัติ)