ย้าย Fastboot ไปที่ userspace

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

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

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

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

คำสั่ง ADB

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

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

คำสั่ง Fastboot

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

คำสั่ง คำอธิบาย
reboot recovery
  • รีบูตเข้าสู่ 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 ขึ้นไปเพื่อรองรับ RAM ของผู้ให้บริการแบบแฟลช

นี่เป็นตัวแปรพิเศษของคําสั่งแฟลช การดำเนินการนี้จะทํางานกับฟังก์ชันรูปภาพ 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

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

คำสั่ง คำอธิบาย
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 จะเปิดใช้โปรแกรมบูต (แทน fastbootd) เพื่อแฟลชพาร์ติชัน

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

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

HAL ของ OEM สำหรับ Fastboot

หากต้องการแทนที่ 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 ในพื้นที่ผู้ใช้ ให้เรียกใช้ชุดทดสอบของผู้ให้บริการ (VTS)

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

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

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

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

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

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

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

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

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

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

    ดึงข้อมูล vendor_boot image ราวกับมีการเรียกใช้ fastboot fetch

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

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

Mkbootimg

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

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

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