העברת אתחול מהיר למרחב המשתמשים

Fastboot הוא השם של המודול והמצב של תוכנת האתחול. בגרסאות Android 10 ואילך יש תמיכה במחיצות שניתן לשנות את הגודל שלהן, על ידי העברת ההטמעה של fastboot מ-bootloader למרחב המשתמש. ההעברה מאפשרת להעביר את הקוד להצתה למיקום משותף שניתן לתחזוקה ולבדיקה, שבו רק החלקים הספציפיים לספק של fastboot מוטמעים על ידי שכבת הפשטה של חומרה (HAL). בנוסף, ב-Android 12 ואילך יש תמיכה בעדכון של דיסקים של זיכרון RAM באמצעות פקודת fastboot נוספת.

איחוד של fastboot ו-recovery

מאחר שהאתחול המהיר והשחזור של מרחב המשתמשים דומים, אפשר למזג אותם מחיצה או בינארית. כך אפשר ליהנות מיתרונות כמו שימוש בפחות מקום, פחות מחיצות באופן כללי ושיתוף הליבה והספריות של fastboot ושל recovery.

Fastbootd הוא שם של דימון ומצב במרחב המשתמש. כדי לתמוך ב-fastbootd, מנהל האתחול צריך להטמיע פקודה חדשה של boot-fastboot לבקרת אתחול (BCB). כדי להיכנס למצב fastbootd, מנהל האתחול כותב את הערך boot-fastboot בשדה הפקודה של הודעת ה-BCB, ולא משנה את השדה recovery של ה-BCB (כדי לאפשר הפעלה מחדש של משימות שחזור שהופסק). גם השדות status, stage ו-reserved לא ישתנו. תוכנת האתחול נטענת בתמונת השחזור ומתחילה להיכנס אליה לאחר שרואים את boot-fastboot בשדה הפקודה של BCB. לאחר מכן, תהליך השחזור מנתח את הודעת ה-BCB ומעביר את המכשיר למצב fastbootd.

פקודות ADB

בקטע הזה מתוארת הפקודה adb לשילוב fastbootd. הפקודה מניבה תוצאות שונות, בהתאם לכך שהיא מופעלת על ידי המערכת או על ידי התהליך לשחזור.

הוראה תיאור
reboot fastboot
  • בוצעה הפעלה מחדש לתוך fastbootd (מערכת).
  • נכנסים ישירות ל-fastbootd בלי הפעלה מחדש (שחזור).

פקודות Fastboot

בקטע הזה מתוארות פקודות fastboot לשילוב fastbootd, כולל פקודות חדשות להצגת פלאש ולניהול מחיצות לוגיות. במידה מסוימת לפקודות יש תוצאות שונות, בהתאם לקיומן של פקודות של תוכנת האתחול או של fastbootd.

הוראה תיאור
reboot recovery
  • הפעלות מחדש לצורך שחזור (תוכנת אתחול).
  • מעבר ישירות למצב שחזור בלי הפעלה מחדש (fastbootd).
reboot fastboot הפעלה מחדש תתבצע בעוד fastbootd.
getvar is-userspace
  • הפונקציה מחזירה את הערך yes (fastbootd).
  • הפונקציה מחזירה את הערך no (תוכנת אתחול).
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 מציגה משתנה של תוכנת אתחול או את כל המשתנים. אם המשתנה לא קיים, מחזירה שגיאה.
set_active <slot>

הגדרת חריץ ההפעלה של A/B הנתון כ-active. ב- ניסיון האתחול, האתחול של המערכת מהחריץ שצוין.

בתמיכה ב-A/B, חריצי זיכרון הם קבוצות כפולות של מחיצות שאפשר להפעיל מהן בנפרד. השמות של המשבצות הם a, b וכן הלאה, וההבחנה ביניהם באמצעות הוספת הסיומות _a, _b ו- וכן הלאה לשם המחיצה.

reboot המכשיר מופעל מחדש כרגיל.
reboot-bootloader (או reboot bootloader) הפעלה מחדש של המכשיר לתוכנת האתחול.
fastboot fetch vendor_boot <out.img>

משתמשים ב-Android מגרסה 12 ואילך כדי לתמוך באחסון RAM מהיר (ramdisk) של ספקים לצורך פלאש.

הפונקציה מקבלת את גודל המחיצה כולה ואת גודל הקטע. מקבלת נתונים לכל מקטע, ואז מחברת את הנתונים יחד ל-<out.img>

מידע נוסף מופיע כאן: fastboot fetch vendor_boot <out.img>.

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

משתמשים ב-Android 12 ואילך כדי לתמוך ב-flashing של דיסקים של זיכרון 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 ואילך כדי לתמוך ב-flashing של דיסקים של זיכרון RAM של ספקים.

אחזור התמונה של vendor_boot. הפונקציה מחזירה שגיאה אם הספק כותרת האתחול היא גרסה 3. אם מדובר בגרסה 4, המערכת תמצא את קטע ה-ramdisk הנכון של הספק (אם הוא זמין). הוא מחליף אותו בתמונה הנתונה, מחשב מחדש את הגדלים וההיסט, ומחזיר את ה-vendor_boot image החדש באופן מהבהב.

פרטים נוספים זמינים במאמר fastboot flash vendor_boot:<foo> <vendor-ramdisk.img>.

Fastboot ותוכנת האתחול

תוכנת האתחול מבצעת איפוס (flash) של המחיצות bootloader,‏ radio ו-boot/recovery, ולאחר מכן המכשיר מופעל במצב fastboot (מרחב המשתמש) ומתבצע איפוס של כל המחיצות האחרות. מנהל האתחול צריך לתמוך בפקודות הבאות.

הוראה תיאור
download הורדת התמונה להבהוב.
flash recovery <image>/ flash boot <image>/ flash bootloader <image>/ מפעילה את המחיצה ותוכנת האתחול של recovery/boot.
reboot הפעלת המכשיר מחדש.
reboot fastboot מופעל מחדש לצורך אתחול מהיר (fastboot).
reboot recovery הפעלה מחדש לצורך שחזור.
getvar קבלת משתנה של תוכנת אתחול שנדרש להבהוב של שחזור/אתחול תמונה (לדוגמה, current-slot ו- max-download-size).
oem <command> הפקודה הוגדרה על ידי ה-OEM (יצרן הציוד המקורי).

מחיצות דינמיות

תוכנת האתחול לא יכולה לאפשר את ההבהוב או המחיקה של מחיצות דינמיות וחייב להחזיר שגיאה אם מבצעים את הפעולות האלה. במכשירים עם מחיצה דינמית מותאמת, הכלי Fastboot (ו-bootloader) תומכים במצב כפייה כדי לבצע איפוס (flash) ישירות של מחיצה דינמית במצב bootloader. לדוגמה, אם system הוא מחיצה דינמית במכשיר שעבר התאמה, שימוש בפקודה fastboot --force flash system מאפשר למחולל האתחול (במקום fastbootd) לבצע את הפלאש של המחיצה.

טעינה במצב כבוי

אם המכשיר תומך בטעינה במצב אופליין או באתחול אוטומטי אחר במצב של הפעלת חובה להשתמש בפקודה fastboot oem off-mode-charge 0 לעקוף את המצבים המיוחדים האלה, כך שהמכשיר יופעל כאילו המשתמש לחץ על לחצן ההפעלה.

אתחול מהיר של OEM (יצרן ציוד מקורי) HAL

כדי להחליף לגמרי את האתחול המהיר של תוכנת האתחול, תהליך האתחול המהיר חייב לטפל בכל פקודות לאתחול מהיר (fastboot). הרבה מהפקודות האלה מגיעות מיצרני ציוד מקורי (OEM) ומתועדות, אבל לדרוש הטמעה מותאמת אישית. הרבה פקודות ספציפיות ליצרני ציוד מקורי לא מתועדות. כדי לטפל בפקודות כאלה, רכיב האתחול המהיר HAL מציין פקודות 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 לאתחול מהיר, בקרת אתחול HAL ו-HAL כלולים באריזה כחלק מתמונת השחזור.

  3. יש להוסיף את כל הרשאות SEPolicy הספציפיות למכשיר הנדרשות על ידי fastbootd. לדוגמה, כדי להפעיל את הפלאש של מחיצה ספציפית למכשיר, צריך הרשאת כתיבה ל-fastbootd. בנוסף, הטמעת תקן HAL מסוג אתחול מהיר (fastboot) עשויה גם מחייבות הרשאות ספציפיות למכשיר.

כדי לאמת את האתחול המהיר של מרחב המשתמשים, צריך להריץ את חבילת הבדיקה של הספק (VTS).

דיסקים של זיכרון RAM של ספקי פלאש

ב-Android מגרסה 12 ואילך יש תמיכה ב: מהבהבים של ramdisk עם פקודת אתחול מהירה נוספת שמושכת את כל תשומת הלב תמונה אחת (vendor_boot) מהמכשיר. הפקודה מפעילה את הכלי fastboot בצד המארח כדי לקרוא את כותרת האתחול של הספק, ליצור קובץ אימג' מחדש ולהפעיל את הקובץ החדש.

כדי לשלוף את התמונה המלאה של vendor_boot, נוספה הפקודה fetch:vendor_boot גם לפרוטוקול אתחול מהיר (fastboot) וגם בהטמעת פרוטוקול משלוח מהיר (fastbootd) ב-Android 12. חשוב לשים לב ש-Fastbootd כן אבל תוכנת האתחול עצמה עשויה שלא לעשות זאת. יצרני ציוד מקורי יכולים להוסיף את הפקודה fetch:vendor_boot בהטמעת תוכנת האתחול של של Google. אבל אם הפקודה לא מזוהה במצב תוכנת האתחול, הבהוב ramdisk של ספק ספציפי במצב תוכנת אתחול אינו נתמך על ידי ספק כאפשרות.

שינויים ב-Bootloader

הפקודות getvar:max-fetch-size ו-fetch:name מוטמעות ב-fastbootd. כדי לתמוך בעדכון של דיסקים של זיכרון RAM של ספקים ב-bootloader, צריך להטמיע את שתי הפקודות האלה.

שינויי אתחול מהיר (Fastbootd)

getvar:max-fetch-size דומה ל-max-download-size. הוא מציין את הגודל המקסימלי שהמכשיר יכול לשלוח בתשובת DATA אחת. הנהג לא יכול לאחזר גודל גדול מהערך הזה.

האפליקציה fetch:name[:offset[:size]] מבצעת סדרה של בדיקות במכשיר. אם כל התנאים הבאים מתקיימים, הפקודה fetch:name[:offset[:size]] מחזירה נתונים:

  • במכשיר פועל build שניתן לניפוי באגים.
  • נעילת המכשיר בוטלה (מצב האתחול כתום).
  • שם המחיצה שאוחזרה הוא 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 (או של שניהם), המערכת משתמשת בערכי ברירת המחדל: 0 עבור offset ו-partition_size - offset המחושב עבור size.

  • צוין היסט, הגודל לא צוין: size = partition_size - offset
  • לא צוין: ערכי ברירת מחדל משמשים לשניהם, 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, הוא מבצע את הפעולות הבאות:
      • מחליפה את ה-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 של הספק בשם ramdisk_<var>&lt;foo></var>. אם לא נמצאה התאמה, או אם יש כמה התאמות, הפונקציה מחזירה שגיאה.
      • החלפת קטע ה-ramdisk של הספק בתמונה שצוינה.
      • מחשבת מחדש כל גודל והיסט בטבלת ה-ramdisk של הספק.
      • איך מעדכנים את קובץ האימג' החדש של vendor_boot.
    • אם אין הגדרה של <foo>, התכונה תנסה למצוא את ramdisk_.

mkbootimg

השם default שמור למתן שמות למקטעי ramdisk של הספק ב- Android מגרסה 12 ואילך. הסמנטיקה של flash vendor_boot:default ב-fastboot לא השתנתה, אבל אסור לתת לשברים של ה-ramdisk את השם default.

שינויים ב-SELinux

בוצע שינוי ב-fastbootd.te כדי לתמוך ב-flashing של דיסקים של זיכרון RAM של ספקים.