בדף הזה מוסבר בפירוט איך יוצרים ליבות בהתאמה אישית למכשירי Android. בהוראות האלה מוסבר איך לבחור את המקורות הנכונים, ליצור את הליבה ולהטמיע את התוצאות בקובץ אימג' של מערכת שנוצר מ-Android Open Source Project (AOSP).
אפשר לקבל מקורות ליבה עדכניים יותר באמצעות Repo, וליצור אותם בלי הגדרות נוספות על ידי הפעלת build/build.sh
מהשורש של בדיקת המקור.
הורדת מקורות וכלי build
לליבת Linux מהדורות אחרונות, משתמשים ב-repo
כדי להוריד את המקורות, ערכת הכלים וסקריפטי ה-build.
לליבת מערכת הפעלה מסוימות (למשל, הליבות של 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 שאפשר להשתמש בהן עם הפקודה הקודמת 'repo init': הסתעפויות של הליבה ומערכות ה-build שלהן.
פרטים על הורדה וקמפלקציה של ליבות למכשירי Pixel זמינים במאמר יצירת ליבות Pixel.
פיתוח הליבה
פיתוח באמצעות 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
, מיקום הפריטים שנוצרו בתהליך הפיתוח (artifacts) מופיע בפלט של הפקודה. פרטים נוספים זמינים במסמכי העזרה של AOSP.
פיתוח גרסה build באמצעות build.sh (קודמת)
להסתעפויות בגרסה Android 12 ומטה, או להסתעפויות ללא Kleaf:
build/build.sh
הקובץ הבינארי של הליבה, המודולים והתמונה התואמת נמצאים בספרייה out/BRANCH/dist
.
פיתוח המודולים של הספק למכשיר הווירטואלי
ב-Android 13 הושק ה-build של הליבות באמצעות 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 הבאה:
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
איך מאפסים את הליבה ומפעילים אותה באמצעות fastboot
למכשירים העדכניים ביותר יש תוסף של תוכנת אתחול כדי לייעל את התהליך של יצירת קובץ אימג' לאתחול והפעלה שלו.
כדי להפעיל את הליבה בלי הפעלה מחדש (flashing):
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 של הליבה
כדי להתאים אישית את גרסאות ה-build של הליבה לגרסאות build של Kleaf, קראו את מסמכי התיעוד של Kleaf.
התאמה אישית של build הליבה באמצעות build.sh (קודם)
ב-build/build.sh
, תהליך ה-build והתוצאה שלו יכולים להיות מושפעים ממשתני סביבה.
רוב ההגדרות הן אופציונליות, וכל הסתעפות של הליבה צריכה להגיע עם הגדרת ברירת מחדל מתאימה. כאן מפורטות האפשרויות הנפוצות ביותר. רשימה מלאה (ועדכנית) זמינה במאמר build/build.sh
.
משתנה סביבה | תיאור | דוגמה |
---|---|---|
BUILD_CONFIG |
קובץ תצורת build מהמקום שבו אתם מאתחלים את סביבת ה-build.
המיקום צריך להיות מוגדר ביחס לספריית הבסיס של המאגר. ברירת המחדל היא build.config .חובה לליבת ליבה נפוצות. |
BUILD_CONFIG=common/build.config.gki.aarch64 |
CC |
שינוי המהדרר שבו נעשה שימוש. חוזר למהדר ברירת המחדל שמוגדר ב-build.config . |
CC=clang |
DIST_DIR |
ספריית הפלט הבסיסית של הפצת הליבה. | DIST_DIR=/path/to/my/dist |
OUT_DIR |
ספריית הפלט הבסיסית של ה-build של הליבה. | 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, אפשר להפעיל פונקציות שמוגדרות ב-build.config
כחלק מהפקודות שלאחר defconfig.
דוגמה נפוצה היא השבתת אופטימיזציה בזמן קישור (LTO) לליבת crosshatch במהלך הפיתוח. אמנם LTO מועיל לליבת ליבה שפורסמה, אבל העלות הנוספת בזמן ה-build יכולה להיות משמעותית. קטע הקוד הבא, שנוסף ל-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)
}
זיהוי גרסאות ליבה
אפשר לזהות את הגרסה הנכונה ל-build משני מקורות: עץ AOSP וקובץ האימג' של המערכת.
גרסת הליבה מהעץ של AOSP
עץ AOSP מכיל גרסאות ליבה שנוצרו מראש. הגרסה הנכונה מופיעה ביומן של git כחלק מהודעת ה-commit:
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
לא מוטמע בקובץ האימג' של האתחול.
לדוגמה, אפשר ליצור את קובץ האימג' של אתחול GKI באמצעות Kleaf:
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
, צריך קובץ בינארי של דיסק RAM. אפשר לקבל אותו על ידי הורדת קובץ אימג' אתחול של GKI ופריסתו. כל קובץ אימג' של אתחול GKI מהגרסה המשויכת של Android יפעל.
tools/mkbootimg/unpack_bootimg.py --boot_img=boot-5.4-gz.img
mv $KERNEL_ROOT/out/ramdisk gki-ramdisk.lz4
תיקיית היעד היא הספרייה ברמה העליונה של עץ הליבה (ספריית העבודה הנוכחית).
אם אתם מפתחים עם AOSP main, תוכלו להוריד במקום זאת את קובץ הארטיפקט של ה-build של ramdisk-recovery.img
מ-build של aosp_arm64 ב-ci.android.com ולהשתמש בו כקובץ הבינארי של ה-ramdisk.
כשיש קובץ בינארי של דיסק RAM ועותקתם אותו ל-gki-ramdisk.lz4
בתיקיית השורש של build הליבה, אפשר ליצור קובץ אימג' של אתחול באמצעות הפקודה:
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
הקובץ הזה נמצא בספריית הארטיפקטים $KERNEL_ROOT/out/$KERNEL_VERSION/dist
.
קובץ האימג' של האתחול נמצא ב-out/<kernel branch>/dist/boot.img
.