ย้าย Fastboot ไปยังพื้นที่ผู้ใช้

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

รวม Fastboot และการกู้คืน

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

Fastbootd คือชื่อของแดมอนและโหมดในพื้นที่ผู้ใช้ หากต้องการรองรับ fastbootd Bootloader ต้องใช้คำสั่งบล็อกควบคุมการบูต (BCB) ใหม่ของ boot-fastboot หากต้องการเข้าสู่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 แสดงผลชื่อของพาร์ติชันหลัก ชื่อจะมีคำต่อท้ายของสล็อตปัจจุบัน หากการแบ่งพาร์ติชันแบบ Super เป็นการแบ่งพาร์ติชัน A/B (โดยปกติจะไม่ใช่)
create-logical-partition <partition> <size> สร้างพาร์ติชันเชิงตรรกะที่มีชื่อและขนาดที่ระบุ ชื่อต้องไม่ มีอยู่แล้วเป็นพาร์ติชันเชิงตรรกะ
delete-logical-partition <partition> ลบพาร์ติชันเชิงตรรกะที่ระบุ (ล้างพาร์ติชัน)
resize-logical-partition <partition> <size> ปรับขนาดพาร์ติชันเชิงตรรกะเป็นขนาดใหม่โดยไม่เปลี่ยนแปลงเนื้อหา ล้มเหลวหากมีพื้นที่ว่างไม่เพียงพอที่จะทำการปรับขนาด
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 ขึ้นไปเพื่อรองรับการแฟลช Vendor 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 ขึ้นไปเพื่อ รองรับการแฟลช Vendor Ramdisk

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

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

Fastboot และ Bootloader

Bootloader จะแฟลชพาร์ติชัน 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 กำหนด

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

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

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

หากต้องการตรวจสอบ fastboot ในพื้นที่ผู้ใช้ ให้เรียกใช้ชุดทดสอบของผู้ให้บริการ (VTS)

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

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

หากต้องการดึงรูปภาพ vendor_boot แบบเต็ม เราได้เพิ่มคำสั่ง fetch:vendor_boot ลงในทั้งโปรโตคอล fastboot และการติดตั้งใช้งานโปรโตคอล fastbootd ใน Android 12 โปรดทราบว่า fastbootd รองรับ การดำเนินการนี้ แต่ Bootloader เองอาจไม่รองรับ OEM สามารถเพิ่มคำสั่ง fetch:vendor_boot ลงในการใช้งาน Bootloader ของโปรโตคอลได้ อย่างไรก็ตาม หากระบบไม่รู้จักคำสั่งในโหมด Bootloader แสดงว่าการแฟลช Ramdisk ของผู้ให้บริการแต่ละรายในโหมด 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 อย่าง: ใช้ค่าเริ่มต้นสำหรับทั้ง 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 ระบบจะดำเนินการต่อไปนี้
      • แทนที่ ramdisk ของผู้ให้บริการด้วยรูปภาพที่ระบุ
      • กะพริบรูปภาพ vendor_boot ใหม่
    • หากส่วนหัวของ Vendor Boot เป็นเวอร์ชัน 4 ระบบจะทำสิ่งต่อไปนี้
      • แทนที่ vendor ramdisk ทั้งหมดด้วยรูปภาพที่ระบุเพื่อให้รูปภาพที่ระบุกลายเป็น vendor_boot image เพียงชิ้นเดียวใน vendor ramdisk
      • คำนวณขนาดและการชดเชยในตาราง ramdisk ของผู้ให้บริการอีกครั้ง
      • กะพริบรูปภาพ vendor_boot ใหม่
  • fastboot flash vendor_boot:foo vendor-ramdisk.img

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

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

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

mkbootimg

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

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

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