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

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

איחוד אתחול מהיר ושחזור

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

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

פקודות ADB

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

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

פקודות 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 ואילך כדי לתמוך ב-ramdisks של ספקים מהבהבים.

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

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

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

צריך להשתמש ב-Android 12 ואילך כדי לתמוך ב-ramdisk מהבהב של ספקים.

זוהי וריאציה מיוחדת של פקודת ה-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 ואילך כדי תמיכה בהבהוב של ramdisks של ספקים.

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

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

אתחול מהיר ותוכנת אתחול

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

הוראה תיאור
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 (יצרן הציוד המקורי).

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

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

טעינה ללא חיבור לאינטרנט

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

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

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

ההגדרה של אתחול מהיר עם 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).

ramdisks של ספקי Flash

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

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

שינויים בתוכנת האתחול

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

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

  • צוין היסט, הגודל לא צוין: size = partition_size - offset
  • לא צוין: ערכי ברירת מחדל משמשים לשניהם, size = partition_size - 0.

לדוגמה, fetch:foo מאחזר את כל המחיצה של foo בהיסט 0.

שינויים במנהל ההתקן

הפקודות נוספו לכלי האתחול המהיר כדי להטמיע שינויים במנהל ההתקן. כל אחד הוא מקושר להגדרה המלאה שלו בטבלה 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 של הספק בשם foo. אם הוא לא נמצא, או אם יש מספר התאמות, הפונקציה תחזיר שגיאה.
      • מחליפה את המקטע של Ramdisk של הספק בתמונה הנתונה.
      • מחשבת מחדש כל גודל והיסט בטבלת ה-ramdisk של הספק.
      • ההבהוב של תמונת vendor_boot החדשה.

Mkbootimg

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

שינויים ב-SELinux

בוצע שינוי ב- fastbootd.te כדי לתמוך בהבהוב של ramdisk עבור ספקים.