בדף הזה מוסבר איך ליצור ליבות בהתאמה אישית למכשירי Android. בהוראות האלה מוסבר איך לבחור את המקורות המתאימים, ליצור את ליבת המערכת ולהטמיע את התוצאות בקובץ אימג' של המערכת שנבנה מתוך פרויקט Android בקוד פתוח (AOSP).
הורדת מקורות וכלים לבנייה
בליבות עדכניות, משתמשים ב-repo
כדי להוריד את המקורות, את ערכת הכלים ואת סקריפטים הבנייה.
חלק מהקרנלים (לדוגמה, קרנלים של Pixel 3) דורשים מקורות מכמה מאגרי git, בעוד שאחרים (לדוגמה, קרנלים נפוצים) דורשים רק מקור אחד. השימוש בגישה repo
מבטיח הגדרה נכונה של ספריית המקור.
מורידים את המקורות של הענף המתאים:
mkdir android-kernel && cd android-kernel
repo init -u https://android.googlesource.com/kernel/manifest -b BRANCH
repo sync
רשימה של ענפים במאגר (BRANCH) שאפשר להשתמש בהם עם הפקודה הקודמת `repo init` זמינה במאמר ענפי ליבה ומערכות הבנייה שלהם.
פרטים על הורדה והידור של ליבות למכשירי Pixel זמינים במאמר בנושא בניית ליבות Pixel.
הרכבת הליבה
Build with Bazel (Kleaf)
ב-Android 13 הוצגה האפשרות ליצור ליבות באמצעות Bazel.
כדי ליצור הפצה של ליבת GKI לארכיטקטורת aarch64, צריך לבדוק ענף של ליבת Android Common Kernel מגרסה Android 13 ואילך, ואז להריץ את הפקודה הבאה:
tools/bazel run //common:kernel_aarch64_dist [-- --destdir=$DIST_DIR]
לאחר מכן, הקובץ הבינארי של הליבה, המודולים והתמונות התואמות ממוקמים בספרייה $DIST_DIR
. אם לא מציינים את --destdir
, אפשר לראות את הפלט של הפקודה כדי לדעת איפה נמצאים פריטי המידע שנוצרו בתהליך הפיתוח (Artifact). פרטים נוספים זמינים במסמכי התיעוד בנושא AOSP.
איך בונים באמצעות build.sh (מאמר שמתייחס לגרסה קודמת)
להסתעפויות ב-Android 12 ומטה, או להסתעפויות ללא Kleaf:
build/build.sh
הקובץ הבינארי של הליבה, המודולים והתמונה המתאימה ממוקמים בספרייה out/BRANCH/dist
.
יצירת מודולים של ספקים למכשיר הווירטואלי
ב-Android 13 הוצגה האפשרות לבנות ליבות באמצעות Bazel (Kleaf), במקום build.sh
.
כדי ליצור הפצה למודולים של virtual_device
, מריצים את הפקודה:
tools/bazel run //common-modules/virtual-device:virtual_device_x86_64_dist [-- --destdir=$DIST_DIR]
לפרטים נוספים על בניית ליבות של Android באמצעות Bazel, אפשר לעיין במאמר. Kleaf – בניית ליבות של Android באמצעות Bazel.
פרטים על תמיכת Kleaf בארכיטקטורות ספציפיות זמינים במאמר בנושא תמיכת Kleaf במכשירים ובליבות.
יצירת מודולים של הספק למכשיר הווירטואלי באמצעות build.sh (גרסה קודמת)
ב-Android 12, Cuttlefish ו-Goldfish מתאחדים, כך שהם חולקים את אותו ליבה: virtual_device
. כדי ליצור את המודולים של ליבת המערכת, משתמשים בהגדרת הבנייה הזו:
BUILD_CONFIG=common-modules/virtual-device/build.config.virtual_device.x86_64 build/build.sh
ב-Android 11 הוצג GKI, שמפריד את הליבה לתמונת ליבה שמתוחזקת על ידי Google ולמודולים שמתוחזקים על ידי הספק, שנבנים בנפרד.
בדוגמה הזו מוצגת הגדרה של תמונת ליבה:
BUILD_CONFIG=common/build.config.gki.x86_64 build/build.sh
בדוגמה הזו מוצגת הגדרת מודול (Cuttlefish ו-Emulator):
BUILD_CONFIG=common-modules/virtual-device/build.config.cuttlefish.x86_64 build/build.sh
הרצת ליבת הקרנל
יש כמה דרכים להפעיל ליבת מערכת בהתאמה אישית. בהמשך מפורטות דרכים מוכרות שמתאימות לתרחישי פיתוח שונים.
הטמעה ב-build של תמונת Android
מעתיקים את Image.lz4-dtb
למיקום המתאים של הקובץ הבינארי של הליבה בעץ AOSP, ובונים מחדש את תמונת האתחול.
אפשר גם להגדיר את המשתנה TARGET_PREBUILT_KERNEL
בזמן השימוש בפקודה make bootimage
(או בכל פקודה אחרת בשורת הפקודה make
שיוצרת תמונת אתחול). המשתנה הזה נתמך בכל המכשירים כי הוא מוגדר דרך device/common/populate-new-device.sh
. לדוגמה:
export TARGET_PREBUILT_KERNEL=DIST_DIR/Image.lz4-dtb
הפעלה של ליבות (kernel) וטעינה שלהן באמצעות fastboot
ברוב המכשירים החדשים יש תוסף לתוכנת האתחול שמייעל את התהליך של יצירת תמונת אתחול והפעלת אתחול.
כדי להפעיל את הליבה בלי להפעיל את ה-flash:
adb reboot bootloader
fastboot boot Image.lz4-dtb
בשיטה הזו, הליבה לא באמת מוצגת, והיא לא תישמר אחרי הפעלה מחדש.
הרצת ליבות ב-Cuttlefish
אתם יכולים להריץ ליבות בארכיטקטורה שתבחרו במכשירי Cuttlefish.
כדי להפעיל מכשיר Cuttlefish עם קבוצה מסוימת של ארטיפקטים של ליבת המערכת, מריצים את הפקודה cvd create
עם הארטיפקטים של ליבת המערכת הרלוונטיים כפרמטרים. בדוגמה הבאה של פקודה נעשה שימוש בארטיפקטים של ליבת מערכת ההפעלה עבור יעד arm64 ממניפסט הליבה common-android14-6.1
.
cvd create \
-kernel_path=/$PATH/$TO/common-android14-6.1/out/android14-6.1/dist/Image \
-initramfs_path=/$PATH/$TO/common-android14-6.1/out/android14-6.1/dist/initramfs.img
מידע נוסף זמין במאמר בנושא פיתוח ליבות ב-Cuttlefish.
התאמה אישית של ה-build של ליבת המערכת
כדי להתאים אישית את הגרסאות של ליבת ה-Kleaf, אפשר לעיין במסמכי התיעוד של Kleaf.
התאמה אישית של ה-build של הליבה באמצעות build.sh (גרסה קודמת)
ב-build/build.sh
, משתני סביבה יכולים להשפיע על תהליך ה-build ועל התוצאה שלו.
רובם אופציונליים, ולכל ענף של ליבת המערכת צריכה להיות הגדרת ברירת מחדל מתאימה. ריכזנו כאן את קיצורי הדרך הנפוצים ביותר. רשימה מלאה (ומעודכנת) זמינה build/build.sh
.
משתנה סביבה | תיאור | דוגמה |
---|---|---|
BUILD_CONFIG |
קובץ תצורת ה-build שממנו מאתחלים את סביבת ה-build.
המיקום צריך להיות מוגדר ביחס לספריית הבסיס של Repo. ברירת המחדל היא build.config .חובה לליבות נפוצות. |
BUILD_CONFIG=common/build.config.gki.aarch64 |
CC |
שינוי ההגדרות של הקומפיילר שבו רוצים להשתמש. חוזר לקומפיילר שמוגדר כברירת מחדל על ידי build.config . |
CC=clang |
DIST_DIR |
ספריית הפלט הבסיסית להפצת הליבה. | DIST_DIR=/path/to/my/dist |
OUT_DIR |
ספריית הפלט הבסיסית של בניית הליבה. | OUT_DIR=/path/to/my/out |
SKIP_DEFCONFIG |
דילוג make defconfig |
SKIP_DEFCONFIG=1 |
SKIP_MRPROPER |
דילוג make mrproper |
SKIP_MRPROPER=1 |
הגדרת ליבה בהתאמה אישית לגרסאות build מקומיות
ב-Android מגרסה 14 ואילך, אפשר להשתמש בקטעי defconfig כדי להתאים אישית את הגדרות הליבה. מידע נוסף זמין במסמכי Kleaf בנושא קטעי defconfig.
הגדרת ליבה בהתאמה אישית לגרסאות build מקומיות באמצעות הגדרות build (מאמר שמתייחס לגרסה קודמת)
ב-Android מגרסה 13 ומטה, אפשר לראות את ההוראות הבאות.
אם אתם צריכים לשנות באופן קבוע אפשרות הגדרה של ליבת מערכת ההפעלה, למשל כשאתם עובדים על תכונה, או אם אתם צריכים להגדיר אפשרות למטרות פיתוח, אתם יכולים לשמור על הגמישות הזו על ידי שמירה של שינוי מקומי או עותק של הגדרות ה-build.
מגדירים את המשתנה POST_DEFCONFIG_CMDS להוראה שמוערכת מיד אחרי השלמת השלב הרגיל make defconfig
. מכיוון שהקבצים build.config
נכללים בסביבת הבנייה, אפשר לקרוא לפונקציות שמוגדרות ב-build.config
כחלק מהפקודות של post-defconfig.
דוגמה נפוצה היא השבתה של אופטימיזציה בזמן הקישור (LTO) עבור ליבות של crosshatch במהלך הפיתוח. למרות שה-LTO מועיל לליבות שפורסמו,
התקורה בזמן הבנייה יכולה להיות משמעותית. הקטע הבא נוסף ל-build.config
המקומי כדי להשבית את LTO באופן קבוע כשמשתמשים ב-build/build.sh
.
POST_DEFCONFIG_CMDS="check_defconfig && update_debug_config"
function update_debug_config() {
${KERNEL_DIR}/scripts/config --file ${OUT_DIR}/.config \
-d LTO \
-d LTO_CLANG \
-d CFI \
-d CFI_PERMISSIVE \
-d CFI_CLANG
(cd ${OUT_DIR} && \
make O=${OUT_DIR} $archsubarch CC=${CC} CROSS_COMPILE=${CROSS_COMPILE} olddefconfig)
}
זיהוי גרסאות ליבה
אפשר לזהות את הגרסה הנכונה לבנייה משני מקורות: עץ ה-AOSP וקובץ האימג' של המערכת.
גרסת ליבה מעץ AOSP
עץ ה-AOSP מכיל גרסאות ליבה מוכנות מראש. היומן של git מציג את הגרסה הנכונה כחלק מהודעת הקומיט:
cd $AOSP/device/VENDOR/NAME
git log --max-count=1
אם גרסת הליבה לא מופיעה ביומן ה-git, צריך לקבל אותה מתמונת המערכת, כמו שמתואר בהמשך.
גרסת ליבה מתמונת מערכת
כדי לקבוע את גרסת הליבה שבה נעשה שימוש בקובץ אימג' של מערכת, מריצים את הפקודה הבאה על קובץ הליבה:
file kernel
לקובצי Image.lz4-dtb
, מריצים את הפקודה:
grep -a 'Linux version' Image.lz4-dtb
יצירת קובץ אימג' לאתחול
אפשר ליצור אימג' של אתחול באמצעות סביבת ה-build של הליבה.
יצירת קובץ אימג' לאתחול למכשירים עם init_boot
במכשירים עם
מחיצת init_boot
,
קובץ האימג' של האתחול נוצר יחד עם ליבת המערכת. התמונה initramfs
לא מוטמעת בתמונת האתחול.
לדוגמה, באמצעות Kleaf, אפשר ליצור את תמונת האתחול של GKI באמצעות:
tools/bazel run //common:kernel_aarch64_dist [-- --destdir=$DIST_DIR]
עם build/build.sh
(גרסה קודמת), אפשר ליצור את קובץ האימג' לאתחול של GKI באמצעות:
BUILD_CONFIG=common/build.config.gki.aarch64 build/build.sh
קובץ האימג' לאתחול GKI נמצא ב-$DIST_DIR.
יצירת תמונת אתחול למכשירים ללא init_boot (גרסה קודמת)
במכשירים שאין בהם מחיצת init_boot
, צריך קובץ בינארי של ramdisk. אפשר להשיג אותו על ידי הורדה של תמונת אתחול של GKI ופריסה שלה. כל תמונת אתחול של GKI מגרסת Android המשויכת תפעל.
tools/mkbootimg/unpack_bootimg.py --boot_img=boot-5.4-gz.img
mv $KERNEL_ROOT/out/ramdisk gki-ramdisk.lz4
תיקיית היעד היא הספרייה ברמה העליונה של עץ הליבה (ספריית העבודה הנוכחית).
אם אתם מפתחים באמצעות ענף הגרסה האחרון של AOSP, אתם יכולים להוריד את
ramdisk-recovery.img
ארטיפקט הבנייה מגרסת aosp_arm64 בכתובת
ci.android.com ולהשתמש בו כקובץ הבינארי של ה-ramdisk.
אם יש לכם קובץ בינארי של ramdisk והעתקתם אותו אל gki-ramdisk.lz4
בספריית הבסיס של בניית הליבה, תוכלו ליצור תמונת אתחול על ידי הפעלת הפקודה:
BUILD_BOOT_IMG=1 SKIP_VENDOR_BOOT=1 KERNEL_BINARY=Image GKI_RAMDISK_PREBUILT_BINARY=gki-ramdisk.lz4 BUILD_CONFIG=common/build.config.gki.aarch64 build/build.sh
אם אתם עובדים עם ארכיטקטורה מבוססת x86, מחליפים את Image
ב-bzImage
ואת aarch64
ב-x86_64
:
BUILD_BOOT_IMG=1 SKIP_VENDOR_BOOT=1 KERNEL_BINARY=bzImage GKI_RAMDISK_PREBUILT_BINARY=gki-ramdisk.lz4 BUILD_CONFIG=common/build.config.gki.x86_64 build/build.sh
הקובץ הזה נמצא בספריית ה-Artifacts: $KERNEL_ROOT/out/$KERNEL_VERSION/dist
.
תמונת האתחול נמצאת ב-out/<kernel branch>/dist/boot.img
.