หน้านี้จะอธิบายรายละเอียดกระบวนการสร้าง เคอร์เนลที่กำหนดเองสำหรับอุปกรณ์ 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` ก่อนหน้าได้ที่ Kernel branches and their build systems
ดูรายละเอียดเกี่ยวกับการดาวน์โหลดและคอมไพล์เคอร์เนลสำหรับอุปกรณ์ Pixel ได้ที่ การสร้างเคอร์เนลของ Pixel
สร้างเคอร์เนล
สร้างด้วย Bazel (Kleaf)
Android 13 เปิดตัวการสร้างเคอร์เนลด้วย Bazel
หากต้องการสร้างการจัดจำหน่ายสำหรับเคอร์เนล GKI สำหรับสถาปัตยกรรม aarch64 โปรดดู สาขาเคอร์เนลทั่วไปของ Android ที่ไม่เก่ากว่า Android 13 และ จากนั้นเรียกใช้คำสั่งต่อไปนี้
tools/bazel run //common:kernel_aarch64_dist [-- --destdir=$DIST_DIR]
หลังจากนั้นไบนารีเคอร์เนล โมดูล และอิมเมจที่เกี่ยวข้องจะอยู่ในไดเรกทอรี
$DIST_DIR หากไม่ได้ระบุ --destdir ให้ดูเอาต์พุต
ของคำสั่งเพื่อดูตำแหน่งของอาร์ติแฟกต์ โปรดดูรายละเอียดในเอกสารประกอบเกี่ยวกับ AOSP
สร้างด้วย build.sh (เดิม)
สำหรับสาขาที่ใช้ Android 12 หรือต่ำกว่า หรือ สาขาที่ไม่มี Kleaf ให้ทำดังนี้
build/build.sh
ไบนารีของเคอร์เนล โมดูล และอิมเมจที่เกี่ยวข้องจะอยู่ในไดเรกทอรี
out/BRANCH/dist
สร้างโมดูลของผู้ให้บริการสำหรับอุปกรณ์เสมือน
Android 13 ได้เปิดตัวการสร้างเคอร์เนลด้วย Bazel (Kleaf) ซึ่งมาแทนที่ build.sh
หากต้องการสร้างการเผยแพร่สำหรับโมดูลของ virtual_device's ให้เรียกใช้คำสั่งต่อไปนี้
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 และโปรแกรมจำลอง)
BUILD_CONFIG=common-modules/virtual-device/build.config.cuttlefish.x86_64 build/build.sh
เรียกใช้เคอร์เนล
การเรียกใช้เคอร์เนลที่สร้างขึ้นเองทำได้หลายวิธี วิธีที่ทราบซึ่งเหมาะกับสถานการณ์การพัฒนาต่างๆ มีดังนี้
ฝังลงในการสร้างอิมเมจ 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
อุปกรณ์ส่วนใหญ่ที่เพิ่งเปิดตัวมีส่วนขยาย Bootloader เพื่อเพิ่มประสิทธิภาพกระบวนการ สร้างและบูตอิมเมจบูต
วิธีบูตเคอร์เนลโดยไม่ต้องแฟลช
adb reboot bootloaderfastboot boot Image.lz4-dtb
การใช้วิธีนี้ไม่ได้แฟลชเคอร์เนลจริงๆ และจะไม่คงอยู่ เมื่อรีบูต
เรียกใช้เคอร์เนลใน Cuttlefish
คุณสามารถเรียกใช้เคอร์เนลในสถาปัตยกรรมที่ต้องการได้ในอุปกรณ์ Cuttlefish
หากต้องการบูตอุปกรณ์ Cuttlefish ด้วยชุดอาร์ติแฟกต์เคอร์เนลที่เฉพาะเจาะจง ให้เรียกใช้คำสั่ง cvd create โดยมีอาร์ติแฟกต์เคอร์เนลเป้าหมายเป็นพารามิเตอร์ คำสั่งตัวอย่างต่อไปนี้ใช้สิ่งประดิษฐ์ของเคอร์เนลสำหรับเป้าหมาย arm64 จาก
common-android14-6.1ไฟล์ Manifest ของเคอร์เนล
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
ปรับแต่งการสร้างเคอร์เนล
หากต้องการปรับแต่งบิลด์เคอร์เนลสำหรับบิลด์ Kleaf โปรดดู เอกสารประกอบของ Kleaf
ปรับแต่งการสร้างเคอร์เนลด้วย build.sh (เดิม)
สำหรับ build/build.sh ตัวแปรสภาพแวดล้อมอาจส่งผลต่อกระบวนการบิลด์และผลลัพธ์
ส่วนใหญ่เป็นตัวเลือก และแต่ละสาขาของเคอร์เนลควรมาพร้อมกับการกำหนดค่าเริ่มต้นที่เหมาะสม
โดยรายการที่ใช้บ่อยที่สุดจะแสดงที่นี่ ดูรายการทั้งหมด (และรายการล่าสุด) ได้ที่ build/build.sh
| ตัวแปรสภาพแวดล้อม | คำอธิบาย | ตัวอย่าง |
|---|---|---|
BUILD_CONFIG |
สร้างไฟล์การกำหนดค่าจากที่ที่คุณเริ่มต้นสภาพแวดล้อมของบิลด์
ต้องกำหนดตำแหน่งที่สัมพันธ์กับไดเรกทอรีรูทของที่เก็บ
ค่าเริ่มต้นคือ 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 |
การกำหนดค่าเคอร์เนลที่กำหนดเองสำหรับการสร้างในเครื่อง
ใน Android 14 ขึ้นไป คุณอาจใช้ Defconfig Fragments เพื่อปรับแต่งการกำหนดค่าเคอร์เนล โปรดดูเอกสารประกอบ Kleaf เกี่ยวกับ Defconfig Fragments
การกำหนดค่าเคอร์เนลที่กำหนดเองสำหรับการบิลด์ในเครื่องที่มีการกำหนดค่าบิลด์ (เดิม)
ใน Android 13 และต่ำกว่า ให้ดูข้อมูลต่อไปนี้
หากคุณต้องเปลี่ยนตัวเลือกการกำหนดค่าเคอร์เนลเป็นประจำ เช่น เมื่อทำงานกับฟีเจอร์ หรือหากคุณต้องการตั้งค่าตัวเลือกสำหรับการพัฒนา คุณสามารถเพิ่มความยืดหยุ่นได้โดยการรักษาการแก้ไขในเครื่องหรือสำเนาของไฟล์กำหนดค่าบิลด์
ตั้งค่าตัวแปร 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)
}
ระบุเวอร์ชันเคอร์เนล
คุณระบุเวอร์ชันที่ถูกต้องเพื่อใช้สร้างได้จาก 2 แหล่งที่มา ได้แก่ ทรี AOSP และอิมเมจระบบ
เวอร์ชันเคอร์เนลจากโครงสร้าง AOSP
โครงสร้าง AOSP มีเคอร์เนลเวอร์ชันที่สร้างไว้ล่วงหน้า บันทึก git จะแสดงเวอร์ชันที่ถูกต้องเป็นส่วนหนึ่งของข้อความคอมมิต
cd $AOSP/device/VENDOR/NAMEgit log --max-count=1
หากไม่มีเวอร์ชันเคอร์เนลในบันทึก git ให้รับจากอิมเมจระบบตามที่อธิบายไว้ด้านล่าง
เวอร์ชันเคอร์เนลจากอิมเมจระบบ
หากต้องการตรวจสอบเวอร์ชันเคอร์เนลที่ใช้ในอิมเมจระบบ ให้เรียกใช้คำสั่งต่อไปนี้กับไฟล์เคอร์เนล
file kernel
สำหรับไฟล์ Image.lz4-dtb ให้เรียกใช้คำสั่งต่อไปนี้
grep -a 'Linux version' Image.lz4-dtb
สร้างอิมเมจการบูต
คุณสร้างอิมเมจบูตได้โดยใช้สภาพแวดล้อมการสร้างเคอร์เนล
สร้างอิมเมจการบูตสำหรับอุปกรณ์ที่มี 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
ไฟล์ดังกล่าวอยู่ในไดเรกทอรีอาร์ติแฟกต์
$KERNEL_ROOT/out/$KERNEL_VERSION/dist
อิมเมจบูตอยู่ที่ out/<kernel branch>/dist/boot.img