ย้าย Fastboot ไปที่ userspace

Fastboot เป็นชื่อของโมดูลและโหมด Bootloader Android 10 ขึ้นไปรองรับพาร์ติชันที่ปรับขนาดได้โดยการย้ายการติดตั้งใช้งาน Fastboot จากบูตโหลดเดอร์ไปยังพื้นที่ผู้ใช้ ช่วงเวลานี้ การย้ายตำแหน่งทำให้สามารถย้ายโค้ด Flash ไปไว้ในที่ที่บำรุงรักษาและทดสอบได้ ตำแหน่งทั่วไปที่มีเฉพาะส่วนของผู้ให้บริการเฉพาะของ Fastboot ที่ใช้งานโดย ชั้นแอบสแตรกชันของฮาร์ดแวร์ (HAL) นอกจากนี้ Android 12 และรุ่นที่สูงกว่า รองรับ RAM ดิสก์ที่กะพริบผ่านคำสั่ง Fastboot ที่เพิ่มขึ้น

รวม Fastboot และ Recovery เข้าด้วยกัน

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

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

คำสั่ง ADB

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

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

คำสั่ง Fastboot

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

คำสั่ง คำอธิบาย
reboot recovery
  • รีบูตเข้าสู่การกู้คืน (bootloader)
  • ป้อนการกู้คืนโดยตรงโดยไม่ต้องรีบูต (fastbootd)
reboot fastboot รีบูตเข้าสู่ fastbootd
getvar is-userspace
  • แสดงผล yes (fastbootd)
  • แสดงผล no (bootloader)
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 ขึ้นไปเพื่อ รองรับ RAMD ของผู้ให้บริการแฟลช

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

ดูรายละเอียดได้ที่ fastboot flash vendor_boot:<foo> <vendor-ramdisk.img>

Fastboot และ Bootloader

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

คำสั่ง คำอธิบาย
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 กำหนด

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

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

การชาร์จนอกโหมด

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

Fastboot OEM HAL

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

คําจํากัดความของ HAL ของ Fastboot มีดังนี้

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. ตรวจสอบว่าได้แพ็กเกจ HAL ของ Fastboot, HAL ของการควบคุมการบูท และ HAL ของการดูแลรักษาไว้เป็นส่วนหนึ่งของอิมเมจการกู้คืน

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

หากต้องการตรวจสอบ Fastboot ของพื้นที่ผู้ใช้ ให้เรียกใช้ Vendor Test Suite (VTS)

แรมดิสก์ของผู้ให้บริการ Flash

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

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

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

คำสั่ง getvar:max-fetch-size และ fetch:name ใช้งานได้ใน fastbootd หากต้องการรองรับการแฟลช RAMdisk ของผู้ให้บริการใน Bootloader คุณต้องใช้งาน 2 คำสั่งนี้

การเปลี่ยนแปลง 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 (หรือทั้ง 2 อย่าง) ฟังก์ชัน ระบบจะใช้ค่าเริ่มต้น ซึ่งสำหรับ offset จะเป็น 0 และสำหรับ size คือ ที่คำนวณได้เป็น partition_size - offset

  • ออฟเซ็ตที่ระบุ ไม่ได้ระบุขนาด: size = partition_size - offset
  • ไม่ได้ระบุ: ค่าเริ่มต้นที่ใช้สำหรับทั้ง 2 อย่าง ได้แก่ 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 จะทำงานดังต่อไปนี้
      • แทนที่ RAM disk ของผู้ให้บริการด้วยรูปภาพที่ระบุ
      • แสดงรูปภาพ vendor_boot ใหม่เป็นภาพกระพริบ
    • ถ้าส่วนหัวการเปิดเครื่องของผู้ให้บริการคือ เวอร์ชัน 4 จะทำงานดังต่อไปนี้
      • แทนที่แรมดิสก์ทั้งหมดของผู้ให้บริการด้วยรูปภาพที่ระบุเพื่อให้รูปภาพที่ระบุกลายเป็นเศษแรมดิสก์ของผู้ให้บริการเพียงรายการเดียวในรูปภาพ vendor_boot
      • คำนวณขนาดและออฟเซ็ตในตาราง RAM ของผู้ให้บริการใหม่
      • กะพริบรูปภาพ vendor_boot ใหม่
  • fastboot flash vendor_boot:foo vendor-ramdisk.img

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

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

      • ค้นหาส่วน RAM ของผู้ให้บริการที่มีชื่อ ramdisk_<var>&lt;foo></var> หากไม่พบหรือมีรายการที่ตรงกันหลายรายการ ระบบจะแสดงข้อผิดพลาด
      • แทนที่ชิ้นส่วน RAMDisk ของผู้ให้บริการด้วยรูปภาพที่ระบุ
      • คำนวณขนาดและออฟเซ็ตแต่ละรายการในตาราง RAM Disk ของผู้ให้บริการอีกครั้ง
      • แสดงรูปภาพ vendor_boot ใหม่เป็นภาพกระพริบ
    • หากไม่ได้ระบุ <foo> ระบบจะพยายามค้นหา ramdisk_

Mkbootimg

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

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

มีการเปลี่ยนแปลงใน fastbootd.te เพื่อรองรับ RAM ดิสก์ของผู้ให้บริการแฟลช