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

בדף הזה מתוארת הסכימה לניהול גרסאות של קובצי אימג' של ליבה גנרית (GKI). ל-Generic Kernel Image‏ (GKI) יש מזהה ייחודי שנקרא גרסת הליבה. הגרסה של הליבה מורכבת מגרסת ממשק המודול של הליבה (KMI) ומהרמה המשנית. הגרסה של הליבה ספציפית לתמונת האימג' שפורסמה, ואילו גרסת ה-KMI מייצגת את הממשק שממנו נוצרה הגרסה. גרסת KMI יכולה לתמוך במספר גרסאות של ליבה. גרסה של ליבה קשורה לגרסה אחת בלבד של 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. המטען הייעודי (payload) של OTA מקודד שדה version לכל מחיצה. כש-update_engine מטפל בעומס נתונים של OTA, הוא משווה את השדה הזה כדי לוודא שהמחיצה לא הורדה לרמה נמוכה יותר.

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

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

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