เลย์เอาต์พาร์ติชัน

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

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

เกี่ยวกับการอัปเดต OTA ของระบบเท่านั้น

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

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

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

ใช้การซ้อนทับของผู้ให้บริการ (<=AOSP 14)

การวางซ้อนของผู้ให้บริการช่วยให้คุณวางซ้อนการเปลี่ยนแปลงใน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 Overlay ไม่สามารถนำไฟล์ออกจากพาร์ติชัน 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 จะมีโมดูลทดสอบสำหรับ Atest ดังนี้

$ atest -v fs_mgr_vendor_overlay_test

อัปเดตเป็นระบบเป็นรูท

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

อัปเดตพาร์ติชัน

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

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

รูปภาพ Ramdisk (ก่อน Android 9) System-as-root (หลังจาก Android 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.img ภายใต้ / (จุดต่อเชื่อม) ด้วย dm-verity AOSP รองรับการใช้งาน dm-verity ต่อไปนี้สำหรับ system.img

vboot 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

vboot 2.0

สำหรับ vboot 2.0 (AVB) Bootloader ต้องผสานรวม external/avb/libavb ซึ่งจะแยกวิเคราะห์ ตัวอธิบาย hashtree สำหรับ /system แปลงเป็น พารามิเตอร์ dm-verity และสุดท้ายส่งพารามิเตอร์ไปยัง เคอร์เนลผ่านบรรทัดคำสั่งของเคอร์เนล (คำอธิบาย 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"

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

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

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