סכמת ניהול גרסאות של GKI

בדף הזה מתוארת הסכימה לניהול גרסאות של קובצי אימג' של ליבה גנרית (GKI). ל-Generic Kernel Image‏ (GKI) יש מזהה ייחודי שנקרא גרסת הליבה. הגרסה של הליבה מורכבת מגרסת ממשק המודול של הליבה (KMI) ומהרמה המשנית. הגרסה של הליבה ספציפית לתמונת האימג' שפורסמה, ואילו גרסת ה-KMI מייצגת את הממשק שממנו נוצרה הגרסה. גרסת KMI יכולה לתמוך במספר גרסאות של ליבה. גרסת ליבה (kernel) קשורה רק לגרסת KMI אחת. במקרה הלא סביר שבו צריך לשנות את ממשק מודול הליבה, היצירה של KMI חוזרת על עצמה כדי לשקף את השינוי בגרסה של KMI.

סיכום התנאים

בטבלה הבאה מפורטים סיכומים של מונחים חשובים שמופיעים בדף הזה ובעדכונים של GKI.

שם סמל דוגמה תיאור
שחרור ליבה w.x.y-zzz-k-suffix 5.4.42-android12-0-foo מזהה ייחודי של גרסה של GKI. זהו הערך שמוחזר על ידי uname.
גרסת KMI w.x-zzz-k 5.4-android12-0 תיאור הממשק של מודול הליבה (KMI) בין GKI לבין מודולי ליבה שניתן לטעון באופן דינמי (DLKM).
רמה משנית y 42 תיאור סדר הגרסאות של הליבה באותה גרסה של KMI.

בטבלה הבאה מפורטים מונחים קשורים נוספים לצורך עיון.

שם סמל דוגמה תיאור
w.x.y w.x.y 5.4.42

פרטים נוספים זמינים במאמר Linux Kernel Makefiles (מחפשים את KERNELRELEASE).

w.x.y מופיע ישירות במסמך הזה. הוא נקרא גם מספר גרסה בן שלושה חלקים. המונח kernel version שמשמש ב-VINTF עלול לגרום לבלבול עם מונחים אחרים, במיוחד w.

המשתנה הזה נקרא kernel_version_tuple ב-libkver.

אסור להקטין את הקבוצה הזו באמצעות עדכונים, כולל OTA או גרסת mainline.

ענף הליבה zzz-w.x android12-5.4 משתמשים במונח הזה בסוגים נפוצים של הסתעפויות ליבה.
גרסה w 5 המונח הזה לא מופיע במסמך הזה. המשתנה הזה נקרא version ב-libkver.
רמת התיקון x 4 המונח הזה לא מופיע במסמך הזה. המשתנה הזה נקרא patch_level ב-libkver.
גרסת Android zzz android12

זהו מספר הגרסה של Android (הקינוח) שאליו הליבה משויכת.

כשמשווים את השדה AndroidRelease, החלק המספרי מחולץ מהמחרוזת לצורך השוואה.

אסור להקטין את מספר הגרסה של Android באמצעות עדכונים, כולל OTA או mainline.

יצירת KMI k 0

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

מספר הדור של KMI מתחיל ב-0.

תכנון ניהול גרסאות

שחרור ליבה

הגדרה

במכשירים שכוללים את GKI, הגרסה של הליבה מוגדרת באופן הבא:

KernelRelease :=
Version.PatchLevel.SubLevel-AndroidRelease-KmiGeneration-suffix
w      .x         .y       -zzz           -k            -something

מידע נוסף זמין במאמר זיהוי גרסת הליבה במכשיר.

הדוגמה הבאה היא של גרסה של ליבה.

5.4.42-android12-0-00544-ged21d463f856

תיאור

גרסת הליבה היא המזהה הייחודי של גרסת GKI. אם לשני קבצים בינאריים של GKI יש אותה שחרור ליבה, הם צריכים להיות זהים מבחינת הבייטים.

מהדורת ליבה מורכבת מגרסה של KMI, מרמת משנה ומסיומת. לצורך המאמר הזה, המערכת מתעלמת מהסיומת אחרי יצירת ה-KMI.

גרסת KMI

הגדרה

גרסת ה-KMI מוגדרת כך:

KmiVersion :=
Version.PatchLevel-AndroidRelease-KmiGeneration
w      .x         -zzz           -k

שימו לב שהרמה המשנית, y, לא נכללת בגרסה של KMI. בדוגמה של Kernel release, גרסת ה-KMI היא:

5.4-android12-0

תיאור

גרסת KMI מתארת את ממשק מודול הליבה (KMI) בין GKI לבין מודולי ליבה שניתן לטעון באופן דינמי (DLKM).

אם לשתי גרסאות של ליבה יש אותה גרסה של KMI, הן מיישמות את אותו ממשק של מודול הליבה. רכיבי ה-DLKM שתואמים לאחד מהם תואמים גם לשני.

אסור להוריד את גרסת ה-KMI באמצעות עדכוני OTA.

רמה משנית

רמת המשנה, y, מתארת את סדר הגרסאות של הליבה באותה גרסת KMI.

בשתי גרסאות ליבה עם אותה גרסת KMI, אבל עם רמת משנה Y1 ו-Y2 בהתאמה:

  • אם Y1 קטן מ-Y2 או שווה לו, מכשיר שפועל בגרסה Y1 יכול לקבל עדכון לגרסה Y2.
  • אם Y1 גדולה מ-Y2, לא ניתן לעדכן מכשיר עם Y1 ל-Y2.

כלומר, אם גרסת ה-KMI לא משתנה, לא ניתן להקטין את רמת המשנה באמצעות עדכון OTA.

איך לזהות את שחרור הליבה של המכשיר

כדי למצוא את הגרסה המלאה של הליבה, מריצים את uname -r או את uname(2) עם קטע הקוד הבא:

std::string get_kernel_release() {
  struct utsname buf;
  return uname(&buf) == 0 ? buf.release : "";
}

פלט לדוגמה:

5.4.42-android12-0-00544-ged21d463f856

במסגרת המסמך הזה, כל מה שקורה אחרי יצירת ה-KMI מתעלם בזמן חילוץ פרטי הליבה. באופן רשמי יותר, מתבצע ניתוח של הפלט של uname -r באמצעות הביטוי הרגולרי הבא (בהנחה ש-zzz מתחיל תמיד ב-"android"):

^(?P<w>\d+)[.](?P<x>\d+)[.](?P<y>\d+)-(?P<z>android\d+)-(?P<k>\d+).*$

המידע שמושמט יכול לכלול מידע כמו מספר ה-build ב-ci.android.com, מספר התיקונים שמתווספים לליבה הבסיסית וגיבוב SHA של השמירה ב-git.

libkver

הספרייה libkver מספקת ממשק C++ לניתוח מהדורת הליבה או מחרוזת של גרסת KMI. רשימה של ממשקי ה-API ש-libkver חושף מופיעה במאמר packages/modules/Gki/libkver/include/kver.

בדיקות VINTF

ב-Android 11 ומטה, יצרני המכשירים מציינים באופן ידני את גרסת Android של קובץ ה-KMI במניפסט של המכשיר. פרטים נוספים זמינים במאמר כללי ההתאמה של הליבה של VINTF.

ב-Android S, אפשר לחלץ מהליבה את החלק של גרסת Android בגרסה של KMI ולהחדיר אותו למניפסט של המכשיר בזמן ה-build.

בדרך כלל, דרישות ההגדרה של הליבה לא משתנות, ולכן אין צורך לקודד את k במטריצה של התאימות. עם זאת, במקרה הנדיר שבו צריך לשנות את דרישות ההגדרה של הליבה, צריך לוודא את הדברים הבאים:

  • הדרישה התואמת תוסר ממטריית התאימות.
  • נוספו בדיקות VTS נוספות כדי לבדוק את הדרישות החדשות מותנות ביצירת KMI.

גרסת קובץ האימג' להפעלה במטא-נתונים של OTA

גם אם קובץ האימג' של האתחול מתעדכן באמצעות עדכון OTA, צריך לעטוף אותו בפורמט של עומס העבודה של OTA, payload.bin. עומס העבודה של OTA מקודד שדה version לכל מחיצה. כש-update_engine מטפל בעומס נתונים של OTA, הוא משווה את השדה הזה כדי לוודא שהמחיצה לא הורדה לרמה נמוכה יותר.

כדי למנוע בלבול, השדה version של מחיצת האתחול במטא-נתונים של OTA נקרא boot image version.

מכיוון ש-ramdisk נוצר תמיד מהתחלה, השימוש בחותמת הזמן של ה-ramdisk מספיק כדי לתאר את קובץ האימג' של האתחול כולו. אין צורך לקודד את גרסת הליבה בגרסה של קובץ האימג' להפעלה, אלא אם אתם מתכוונים לחבר בעתיד קובץ אימג' להפעלה ישן לקובץ בינארי חדש של ליבה.

לפני עדכון OTA, לקוח ה-OTA בודק את גרסת קובץ האימג' של האתחול באותו אופן שבו הוא בודק כל מחיצה אחרת.