การย้าย Fastboot ไปยัง Userspace

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

Unifying fastboot และการกู้คืน

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

เพื่อรองรับ fastbootd bootloader ต้องใช้คำสั่ง boot control block (BCB) ใหม่ของ boot-fastboot ในการเข้าสู่โหมด fastbootd bootloader จะเขียน boot-fastboot ลงในฟิลด์คำสั่งของข้อความ BCB และปล่อยให้ฟิลด์ recovery ของ BCB ไม่เปลี่ยนแปลง (เพื่อเปิดใช้งานการรีสตาร์ทภารกิจการกู้คืนที่ถูกขัดจังหวะ) statusstage และฟิลด์ที่ 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> ] เขียนไฟล์ไปยังพาร์ติชั่นแฟลช อุปกรณ์ต้องอยู่ในสถานะปลดล็อก
erase <partition> ลบพาร์ติชัน (ไม่จำเป็นต้องลบอย่างปลอดภัย) อุปกรณ์ต้องอยู่ในสถานะปลดล็อก
getvar <variable> | all แสดงตัวแปร bootloader หรือตัวแปรทั้งหมด หากไม่มีตัวแปร ให้ส่งคืนข้อผิดพลาด
set_active <slot>

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

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

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

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

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

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

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

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

นี่เป็นรูปแบบพิเศษของคำสั่งแฟลช มันทำหน้าที่ 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 และสูงกว่าเพื่อรองรับ ramdisks ของผู้จำหน่ายที่กระพริบ

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

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

Fastboot และ 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 จะต้องข้ามโหมดพิเศษเหล่านี้ เพื่อให้อุปกรณ์บู๊ตราวกับว่าผู้ใช้กด ปุ่มเปิดปิด

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

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

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

ramdisks ผู้ขายที่กระพริบ

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

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

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

คำสั่ง getvar:max-fetch-size และ fetch:name ถูกนำมาใช้ใน fastbootd เพื่อรองรับ ramdisks ของผู้จำหน่ายที่กระพริบใน 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 ทั้งหมดที่ offset 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 ความหมายยังคงเหมือนเดิม คุณ ต้องไม่ ตั้งชื่อแฟรกเมนต์ ramdisk ของคุณเป็น default

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

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