ย้าย Fastboot ไปที่ userspace

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

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

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

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

คำสั่ง ADB

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

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

คำสั่ง Fastboot

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

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

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

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

ใช้ใน Android 12 ขึ้นไปเพื่อรองรับ RAM ของผู้ให้บริการแบบแฟลช

นี่เป็นรูปแบบพิเศษของคำสั่ง Flash และเรียกใช้ฟังก์ชันรูปภาพ 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 ขึ้นไปเพื่อรองรับ RAM ของผู้ให้บริการแบบแฟลช

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

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

Fastboot และ Bootloader

Bootloader แฟลชพาร์ติชัน bootloader, radio และ boot/recovery หลังจากนั้นอุปกรณ์จะเปิดเครื่องใน Fastboot (userspace) และแฟลชพาร์ติชันอื่นๆ ทั้งหมด 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

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

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

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

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

HAL ของ Fastboot OEM

หากต้องการแทนที่ Fastboot ของ Bootloader โดยสมบูรณ์ 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, HAL การควบคุมการเปิดเครื่อง และ HAL สถานะเป็นส่วนหนึ่งของอิมเมจการกู้คืน

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

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

RAM ของผู้ให้บริการ Flash

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

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

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

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

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

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

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

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

Mkbootimg

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

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

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