ย้าย Fastboot ไปที่ Userspace

Android 10 และสูงกว่ารองรับพาร์ติชันที่ปรับขนาดได้โดยการย้ายการใช้งาน fastboot จาก bootloader ไปยังพื้นที่ผู้ใช้ การย้ายตำแหน่งนี้ทำให้สามารถย้ายโค้ดที่กะพริบไปยังตำแหน่งทั่วไปที่สามารถบำรุงรักษาและทดสอบได้ โดยมีเพียงส่วนของ fastboot เฉพาะผู้จำหน่ายที่นำไปใช้โดย Hardware Abstraction Layer (HAL) นอกจากนี้ Android 12 ขึ้นไปยังรองรับการแฟลช ramdisk ผ่านคำสั่ง fastboot ที่เพิ่มเข้ามา

การรวม fastboot และการกู้คืนเข้าด้วยกัน

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

เพื่อรองรับ fastbootd bootloader ต้องใช้คำสั่ง boot control block (BCB) ใหม่ของ boot-fastboot ในการเข้าสู่โหมด fastbootd นั้น bootloader จะเขียน boot-fastboot ลงในช่องคำสั่งของข้อความ BCB และปล่อยให้ฟิลด์ recovery ของ BCB ไม่เปลี่ยนแปลง (เพื่อเปิดใช้งานการรีสตาร์ทงานการกู้คืนที่ถูกขัดจังหวะ) status stage และฟิลด์ reserved ยังคงไม่เปลี่ยนแปลงเช่นกัน bootloader จะโหลดและบูตเข้าสู่อิมเมจการกู้คืนเมื่อเห็น boot-fastboot ในช่องคำสั่ง BCB การกู้คืนจะแยกวิเคราะห์ข้อความ BCB และสลับไปที่โหมด fastbootd

คำสั่งเอดีบี

ส่วนนี้จะอธิบายคำสั่ง adb สำหรับการรวม fastbootd คำสั่งมีผลลัพธ์ที่แตกต่างกัน ขึ้นอยู่กับว่าจะดำเนินการโดยระบบหรือโดยการกู้คืน

สั่งการ คำอธิบาย
reboot fastboot
  • รีบูตเป็น fastbootd (ระบบ)
  • เข้าสู่ fastbootd โดยตรงโดยไม่ต้องรีบูต (กู้คืน)

คำสั่ง Fastboot

ส่วนนี้อธิบายคำสั่ง fastboot สำหรับการรวม fastbootd รวมถึงคำสั่งใหม่สำหรับการแฟลชและการจัดการโลจิคัลพาร์ติชัน คำสั่งบางคำสั่งมีผลลัพธ์ที่แตกต่างกัน ขึ้นอยู่กับว่าคำสั่งเหล่านั้นถูกเรียกใช้งานโดย bootloader หรือโดย fastbootd

สั่งการ คำอธิบาย
reboot recovery
  • รีบูตเข้าสู่การกู้คืน (bootloader)
  • เข้าสู่การกู้คืนโดยตรงโดยไม่ต้องรีบูต ( fastbootd )
reboot fastboot รีบูตเป็น fastbootd
getvar is-userspace
  • ส่งคืน yes ( fastbootd )
  • ส่งคืน no (บูตโหลดเดอร์)
getvar is-logical: <partition> คืนค่า yes หากพาร์ติชันที่กำหนดเป็นโลจิคัลพาร์ติชัน no ฉะนั้นจะส่งคืนค่าใช่ โลจิคัลพาร์ติชันรองรับคำสั่งทั้งหมดที่แสดงด้านล่าง
getvar super-partition-name ส่งกลับชื่อของพาร์ติชันขั้นสูง ชื่อจะรวมส่วนต่อท้ายสล็อตปัจจุบันด้วยหากพาร์ติชั่นพิเศษเป็นพาร์ติชั่น A/B (โดยปกติจะไม่ใช่)
create-logical-partition <partition> <size> สร้างโลจิคัลพาร์ติชันด้วยชื่อและขนาดที่กำหนด ต้องไม่มีชื่อเป็นโลจิคัลพาร์ติชันอยู่แล้ว
delete-logical-partition <partition> ลบโลจิคัลพาร์ติชันที่กำหนด (ล้างพาร์ติชันอย่างมีประสิทธิภาพ)
resize-logical-partition <partition> <size> ปรับขนาดโลจิคัลพาร์ติชันให้เป็นขนาดใหม่โดยไม่ต้องเปลี่ยนเนื้อหา ล้มเหลวหากมีพื้นที่ว่างไม่เพียงพอที่จะทำการปรับขนาด
update-super <partition> รวมการเปลี่ยนแปลงกับข้อมูลเมตาของพาร์ติชันซุปเปอร์ หากไม่สามารถผสานได้ (เช่น รูปแบบบนอุปกรณ์เป็นเวอร์ชันที่ไม่รองรับ) คำสั่งนี้จะล้มเหลว พารามิเตอร์ wipe เพิ่มเติมจะเขียนทับข้อมูลเมตาของอุปกรณ์ แทนที่จะทำการผสาน
flash <partition> [ <filename> ] เขียนไฟล์ไปยังพาร์ติชันแฟลช อุปกรณ์จะต้องอยู่ในสถานะปลดล็อค
erase <partition> ลบพาร์ติชัน (ไม่จำเป็นต้องเป็นการลบแบบปลอดภัย) อุปกรณ์จะต้องอยู่ในสถานะปลดล็อค
getvar <variable> | all แสดงตัวแปร bootloader หรือตัวแปรทั้งหมด หากไม่มีตัวแปร จะส่งกลับข้อผิดพลาด
set_active <slot>

ตั้งค่าสล็อตการบูต A/B ที่กำหนดเป็น active ในการพยายามบู๊ตครั้งถัดไป ระบบจะบู๊ตจากช่องที่ระบุ

สำหรับการรองรับ A/B สล็อตคือชุดพาร์ติชันที่ซ้ำกันซึ่งสามารถบูตจากแยกกันได้ สล็อตมีชื่อว่า a , b และอื่นๆ และแยกความแตกต่างด้วยการเพิ่มส่วนต่อท้าย _a , _b และอื่นๆ ให้กับชื่อพาร์ติชัน

reboot รีบูตอุปกรณ์ตามปกติ
reboot-bootloader (หรือ reboot bootloader ) รีบูตอุปกรณ์เข้าสู่ bootloader
fastboot fetch vendor_boot <out.img>

ใช้ใน Android 12 และสูงกว่า เพื่อรองรับ ramdisk ของผู้จำหน่ายแบบแฟลช

รับขนาดพาร์ติชันทั้งหมดและขนาดก้อน รับข้อมูลสำหรับแต่ละส่วน จากนั้นรวมข้อมูลเข้าด้วยกันเป็น <out.img>

สำหรับรายละเอียด โปรดดูที่ fastboot fetch vendor_boot <out.img>

fastboot flash vendor_boot:default <vendor-ramdisk.img>

ใช้ใน Android 12 และสูงกว่าเพื่อรองรับ ramdisk ของผู้จำหน่ายแบบแฟลช

นี่เป็นรูปแบบพิเศษของคำสั่งแฟลช มันทำหน้าที่ fetch vendor_boot เหมือนกับว่ามีการเรียก fastboot fetch อิมเมจ vendor_boot ใหม่ที่กะพริบขึ้นอยู่กับว่าเวอร์ชันส่วนหัวการบูตเป็นเวอร์ชัน 3 หรือเวอร์ชัน 4

สำหรับรายละเอียด โปรดดูที่ fastboot flash vendor_boot:default <vendor-ramdisk.img>

fastboot flash vendor_boot: <foo> <vendor-ramdisk.img> ใช้ใน Android 12 และสูงกว่าเพื่อรองรับ ramdisk ของผู้จำหน่ายแบบแฟลช

ดึงข้อมูลอิมเมจ vendor_boot ส่งคืนข้อผิดพลาดหากส่วนหัวการบูตของผู้จำหน่ายเป็นเวอร์ชัน 3 หากเป็นเวอร์ชัน 4 จะค้นหาแฟรกเมนต์ ramdisk ของผู้จำหน่ายที่ถูกต้อง (ถ้ามี) โดยแทนที่ด้วยรูปภาพที่กำหนด คำนวณขนาดและออฟเซ็ตใหม่ และกะพริบ vendor_boot image ใหม่

สำหรับรายละเอียด โปรดดูที่ fastboot flash vendor_boot: <foo> <vendor-ramdisk.img>

Fastboot และบูตโหลดเดอร์

บูตโหลดเดอร์จะกะพริบพาร์ติชัน bootloader , radio และ boot/recovery หลังจากนั้นอุปกรณ์จะบู๊ตเข้าสู่ fastboot (พื้นที่ผู้ใช้) และกะพริบพาร์ติชันอื่นๆ ทั้งหมด bootloader ควรรองรับคำสั่งต่อไปนี้

สั่งการ คำอธิบาย
download ดาวน์โหลดรูปภาพเพื่อแฟลช
flash recovery <image> / flash boot <image> / flash bootloader <image> / กะพริบพาร์ติ recovery/boot และ bootloader
reboot รีบูตอุปกรณ์
reboot fastboot รีบูตเป็น fastboot
reboot recovery รีบูตเพื่อการกู้คืน
getvar รับตัวแปร bootloader ที่จำเป็นสำหรับการแฟลชอิมเมจการกู้คืน/บูต (เช่น current-slot และ max-download-size )
oem <command> คำสั่งที่กำหนดโดย OEM

พาร์ติชันแบบไดนามิก

บูตโหลดเดอร์ ต้องไม่ อนุญาตให้มีการแฟลชหรือการลบพาร์ติชันไดนามิก และ จะต้อง ส่งคืนข้อผิดพลาดหากพยายามดำเนินการเหล่านี้ สำหรับอุปกรณ์พาร์ติชันไดนามิกที่ได้รับการปรับปรุงใหม่ เครื่องมือ fastboot (และ bootloader) รองรับโหมดบังคับเพื่อแฟลชพาร์ติชันไดนามิกโดยตรงขณะอยู่ในโหมด bootloader ตัวอย่างเช่น หาก system เป็นพาร์ติชันแบบไดนามิกบนอุปกรณ์ที่ติดตั้งเพิ่มเติม การใช้คำสั่ง fastboot --force flash system จะเปิดใช้งาน bootloader (แทน fastbootd ) เพื่อแฟลชพาร์ติชัน

การชาร์จแบบปิดโหมด

หากอุปกรณ์รองรับการชาร์จนอกโหมดหรือบูตอัตโนมัติเข้าสู่โหมดพิเศษเมื่อมีการจ่ายไฟ การใช้คำสั่ง fastboot oem off-mode-charge 0 จะต้องข้ามโหมดพิเศษเหล่านี้ เพื่อให้อุปกรณ์บู๊ตราวกับว่าผู้ใช้กด ปุ่มเปิดปิด

Fastboot OEM HAL

หากต้องการแทนที่ bootloader fastboot โดยสมบูรณ์ fastboot จะต้องจัดการคำสั่ง fastboot ที่มีอยู่ทั้งหมด คำสั่งเหล่านี้จำนวนมากมาจาก OEM และได้รับการบันทึกไว้ แต่จำเป็นต้องมีการใช้งานแบบกำหนดเอง คำสั่งเฉพาะของ OEM จำนวนมาก ไม่ได้ รับการบันทึกไว้ ในการจัดการคำสั่งดังกล่าว fastboot HAL จะระบุคำสั่ง OEM ที่จำเป็น ผู้ผลิต OEM สามารถใช้คำสั่งของตนเองได้

คำจำกัดความของ fastboot HAL เป็นดังนี้:

import IFastbootLogger;

/**
 * IFastboot interface implements vendor specific fastboot commands.
 */
interface IFastboot {
    /**
     * Returns a bool indicating whether the bootloader is enforcing verified
     * boot.
     *
     * @return verifiedBootState True if the bootloader is enforcing verified
     * boot and False otherwise.
     */
    isVerifiedBootEnabled() generates (bool verifiedBootState);

    /**
     * Returns a bool indicating the off-mode-charge setting. If off-mode
     * charging is enabled, the device autoboots into a special mode when
     * power is applied.
     *
     * @return offModeChargeState True if the setting is enabled and False if
     * not.
     */
    isOffModeChargeEnabled() generates (bool offModeChargeState);

    /**
     * Returns the minimum battery voltage required for flashing in mV.
     *
     * @return batteryVoltage Minimum battery voltage (in mV) required for
     * flashing to be successful.
     */
    getBatteryVoltageFlashingThreshold() generates (int32_t batteryVoltage);

    /**
     * Returns the file system type of the partition. This is only required for
     * physical partitions that need to be wiped and reformatted.
     *
     * @return type Can be ext4, f2fs or raw.
     * @return result SUCCESS if the operation is successful,
     * FAILURE_UNKNOWN if the partition is invalid or does not require
     * reformatting.
     */
    getPartitionType(string partitionName) generates (FileSystemType type, Result result);

    /**
     * Executes a fastboot OEM command.
     *
     * @param oemCmd The oem command that is passed to the fastboot HAL.
     * @response result Returns the status SUCCESS if the operation is
     * successful,
     * INVALID_ARGUMENT for bad arguments,
     * FAILURE_UNKNOWN for an invalid/unsupported command.
     */
    doOemCommand(string oemCmd) generates (Result result);

};

การเปิดใช้งาน fastbootd

หากต้องการเปิดใช้งาน fastbootd บนอุปกรณ์:

  1. เพิ่ม fastbootd ให้กับ PRODUCT_PACKAGES ใน device.mk : PRODUCT_PACKAGES += fastbootd

  2. ตรวจสอบให้แน่ใจว่า fastboot HAL, Boot Control HAL และ Health HAL ได้รับการแพ็กเกจเป็นส่วนหนึ่งของอิมเมจการกู้คืน

  3. เพิ่มสิทธิ์ SEPolicy เฉพาะอุปกรณ์ใดๆ ที่จำเป็นสำหรับ fastbootd ตัวอย่างเช่น fastbootd ต้องการสิทธิ์การเขียนไปยังพาร์ติชันเฉพาะอุปกรณ์เพื่อแฟลชพาร์ติชันนั้น นอกจากนี้ การใช้งาน fastboot HAL อาจจำเป็นต้องได้รับสิทธิ์เฉพาะอุปกรณ์ด้วย

หากต้องการตรวจสอบ fastboot ของ userspace ให้เรียกใช้ Vendor Test Suite (VTS)

ramdisk ของผู้ขายที่กระพริบ

Android 12 ขึ้นไปรองรับการแฟลชแรมดิสก์ด้วยคำสั่ง fastboot ที่เพิ่มเข้ามาซึ่งจะดึงอิมเมจ vendor_boot แบบเต็มจากอุปกรณ์ คำสั่งจะแจ้งให้เครื่องมือ fastboot ฝั่งโฮสต์อ่านส่วนหัวการบูตของผู้จำหน่าย สร้างอิมเมจใหม่ และแฟลชอิมเมจใหม่

หากต้องการดึงอิมเมจ vendor_boot แบบเต็ม คำสั่ง fetch:vendor_boot จะถูกเพิ่มลงในทั้งโปรโตคอล fastboot และการใช้งาน fastbootd ของโปรโตคอลใน Android 12 โปรดทราบว่า fastbootd จะ ใช้สิ่งนี้ แต่ตัวโหลดบูตเองก็อาจไม่เป็นเช่นนั้น OEM สามารถเพิ่มคำสั่ง fetch:vendor_boot ให้กับการใช้งานโปรโตคอล bootloader ได้ อย่างไรก็ตาม หากไม่รู้จักคำสั่งในโหมด bootloader การแฟลช ramdisk ของผู้จำหน่ายแต่ละรายในโหมด bootloader ก็ไม่ใช่ตัวเลือกที่ผู้ขายสนับสนุน

การเปลี่ยนแปลง Bootloader

คำสั่ง getvar:max-fetch-size และ fetch:name ถูกนำไปใช้ใน fastbootd เพื่อรองรับการแฟลชดิสก์ผู้ขายใน bootloader คุณต้องใช้คำสั่งทั้งสองนี้

การเปลี่ยนแปลง Fastbootd

getvar:max-fetch-size คล้ายกับ max-download-size โดยจะระบุขนาดสูงสุดที่อุปกรณ์สามารถส่งในการตอบกลับ DATA เดียว โปรแกรมควบคุมจะต้องไม่ดึงข้อมูลขนาดใหญ่กว่าค่านี้

fetch:name[:offset[:size]] ดำเนินการตรวจสอบหลายชุดบนอุปกรณ์ หากสิ่งต่อไปนี้ทั้งหมดเป็นจริง คำสั่ง fetch:name[:offset[:size]] จะส่งคืนข้อมูล:

  • อุปกรณ์กำลังใช้งานบิลด์ที่แก้ไขข้อบกพร่องได้
  • อุปกรณ์ถูกปลดล็อคแล้ว (สถานะการบูตสีส้ม)
  • ชื่อพาร์ติชันที่ดึงข้อมูลคือ vendor_boot
  • ค่า size อยู่ภายใน 0 < size <= max-fetch-size

เมื่อสิ่งเหล่านี้ได้รับการตรวจสอบแล้ว fetch:name[:offset[:size]] จะส่งกลับขนาดพาร์ติชันและออฟเซ็ต หมายเหตุสิ่งต่อไปนี้:

  • fetch:name เทียบเท่ากับ fetch:name:0 ซึ่งเทียบเท่ากับ fetch:name:0:partition_size
  • fetch:name:offset เทียบเท่ากับ fetch:name:offset:(partition_size - offset)

ดังนั้น fetch:name[:offset[:size]] = fetch:name:offset:(partition_size - offset)

เมื่อไม่ได้ระบุ offset หรือ partition_size (หรือทั้งสองอย่าง) ค่าดีฟอลต์จะถูกใช้ ซึ่งสำหรับ offset คือ 0 และสำหรับ size คือค่าที่คำนวณได้ของ partition_size - offset

  • ระบุออฟเซ็ต ไม่ระบุขนาด: size = partition_size - offset
  • ไม่ได้ระบุ: ค่าเริ่มต้นที่ใช้สำหรับทั้งสอง size = partition_size - 0

ตัวอย่างเช่น fetch:foo ดึงข้อมูลพาร์ติชัน foo ทั้งหมดที่ออฟเซ็ต 0

การเปลี่ยนแปลงไดรเวอร์

มีการเพิ่มคำสั่งลงในเครื่องมือ fastboot เพื่อใช้การเปลี่ยนแปลงไดรเวอร์ แต่ละอันเชื่อมโยงกับคำจำกัดความแบบเต็มในตาราง คำสั่ง Fastboot

  • fastboot fetch vendor_boot out.img

    • เรียก getvar max-fetch-size เพื่อกำหนดขนาดก้อน
    • เรียก getvar partition-size:vendor_boot[_a] เพื่อกำหนดขนาดของพาร์ติชันทั้งหมด
    • เรียก fastboot fetch vendor_boot[_a]:offset:size สำหรับแต่ละอัน (ขนาดชิ้นใหญ่กว่าขนาด vendor_boot ดังนั้นโดยปกติแล้วจะมีเพียงชิ้นเดียวเท่านั้น)
    • เย็บข้อมูลเข้าด้วยกันเป็น out.img
  • fastboot flash vendor_boot:default vendor-ramdisk.img

    นี่เป็นรูปแบบพิเศษของคำสั่งแฟลช มันจะดึงอิมเมจ vendor_boot เหมือนกับว่ามีการเรียก fastboot fetch

    • หากการบูตของผู้ขายเป็นส่วนหัว เวอร์ชัน 3 จะดำเนินการดังต่อไปนี้:
      • แทนที่ ramdisk ของผู้ขายด้วยอิมเมจที่กำหนด
      • กะพริบอิมเมจ vendor_boot ใหม่
    • หากส่วนหัวการบูตของผู้จำหน่ายเป็น เวอร์ชัน 4 จะดำเนินการดังต่อไปนี้:
      • แทนที่ ramdisk ของผู้จำหน่ายทั้งหมดด้วยอิมเมจที่กำหนด เพื่อให้อิมเมจที่กำหนดกลายเป็นแฟรกเมนต์ ramdisk ของผู้จำหน่ายเพียงตัวเดียวในอิมเมจ vendor_boot
      • คำนวณขนาดและออฟเซ็ตใหม่ในตาราง ramdisk ของผู้ขาย
      • กะพริบอิมเมจ vendor_boot ใหม่
  • fastboot flash vendor_boot:foo vendor-ramdisk.img

    ดึงข้อมูล vendor_boot image เหมือนกับว่ามีการเรียก fastboot fetch

    • หากส่วนหัวการบูตของผู้ขายเป็นเวอร์ชัน 3 จะส่งกลับข้อผิดพลาด
    • หากส่วนหัวการบูตของผู้จำหน่ายเป็นเวอร์ชัน 4 จะดำเนินการดังต่อไปนี้:

      • ค้นหาแฟรกเมนต์ ramdisk ของผู้จำหน่ายที่มีชื่อ foo หากไม่พบ หรือหากมีหลายรายการที่ตรงกัน จะส่งกลับข้อผิดพลาด
      • แทนที่ส่วน ramdisk ของผู้จำหน่ายด้วยอิมเมจที่กำหนด
      • คำนวณแต่ละขนาดและออฟเซ็ตใหม่ในตาราง ramdisk ของผู้ขาย
      • กะพริบอิมเมจ vendor_boot ใหม่

mkbootimg

ชื่อ default สงวนไว้สำหรับการตั้งชื่อแฟรกเมนต์ ramdisk ของผู้จำหน่ายใน Android 12 ขึ้นไป แม้ว่า fastboot flash vendor_boot:default semantics ยังคงเหมือนเดิม คุณ ต้องไม่ ตั้งชื่อแฟรกเมนต์ ramdisk ของคุณเป็น default

การเปลี่ยนแปลง SELinux

มีการเปลี่ยนแปลงใน fastbootd.te เพื่อรองรับการแฟลช ramdisk ของผู้จำหน่าย