หน้านี้แสดงรายละเอียดกระบวนการสร้าง เคอร์เนล แบบกำหนดเองสำหรับอุปกรณ์ Android คำแนะนำเหล่านี้จะแนะนำคุณตลอดกระบวนการเลือกแหล่งที่มาที่ถูกต้อง การสร้างเคอร์เนล และการฝังผลลัพธ์ลงในอิมเมจระบบที่สร้างจาก Android Open Source Project (AOSP)
คุณสามารถรับแหล่งเคอร์เนลล่าสุดได้โดยใช้ Repo ; สร้างโดยไม่ต้องกำหนดค่าเพิ่มเติมโดยการรัน build/build.sh
จากรากของการชำระเงินต้นทางของคุณ
ดาวน์โหลดซอร์สและสร้างเครื่องมือ
สำหรับเคอร์เนลล่าสุด ให้ใช้ repo
เพื่อดาวน์โหลดซอร์ส ทูลเชน และบิลด์สคริปต์ เคอร์เนลบางตัว (เช่น เคอร์เนล Pixel 3) ต้องการแหล่งที่มาจากแหล่งเก็บข้อมูล Git หลายแหล่ง ในขณะที่เคอร์เนลอื่นๆ (เช่น เคอร์เนลทั่วไป) ต้องการแหล่งที่มาเพียงแหล่งเดียว การใช้แนวทาง repo
ช่วยให้มั่นใจได้ว่าการตั้งค่าไดเร็กทอรีต้นทางถูกต้อง
ดาวน์โหลดแหล่งที่มาสำหรับสาขาที่เหมาะสม:
mkdir android-kernel && cd android-kernel
repo init -u https://android.googlesource.com/kernel/manifest -b BRANCH
repo sync
สำหรับรายการสาขา repo ( BRANCH ) ที่สามารถใช้กับคำสั่ง `repo init` ก่อนหน้า โปรดดู สาขาเคอร์เนลและระบบการสร้าง
สำหรับรายละเอียดเกี่ยวกับการดาวน์โหลดและการคอมไพล์เคอร์เนลสำหรับอุปกรณ์ Pixel โปรดดู การสร้าง Pixel Kernels
สร้างเคอร์เนล
สร้างด้วย Bazel (Kleaf)
Android 13 เปิดตัวการสร้างเคอร์เนลด้วย Bazel
หากต้องการสร้างเคอร์เนล GKI สำหรับสถาปัตยกรรม aarch64 ให้ตรวจสอบสาขาเคอร์เนลทั่วไปของ Android ที่ไม่เก่ากว่า Android 13 จากนั้นเรียกใช้คำสั่งต่อไปนี้:
tools/bazel build //common:kernel_aarch64_dist
หากต้องการสร้างการแจกจ่าย ให้รัน:
tools/bazel run //common:kernel_aarch64_dist -- --dist_dir=$DIST_DIR
หลังจากนั้นไบนารีเคอร์เนล โมดูล และอิมเมจที่เกี่ยวข้องจะอยู่ในไดเร็กทอรี $DIST_DIR
หากไม่ได้ระบุ --dist_dir
โปรดดูเอาต์พุตของคำสั่งสำหรับตำแหน่งของส่วนต่างๆ สำหรับรายละเอียด โปรดดู เอกสารประกอบใน AOSP
สร้างด้วย build.sh (ดั้งเดิม)
สำหรับสาขาที่ใช้หรือต่ำกว่า Android 12 หรือสาขาที่ไม่มี Kleaf:
build/build.sh
ไบนารีเคอร์เนล โมดูล และรูปภาพที่เกี่ยวข้องจะอยู่ในไดเร็กทอรี out/ BRANCH /dist
สร้างโมดูลผู้จำหน่ายสำหรับอุปกรณ์เสมือน
Android 13 เปิดตัวการสร้างเคอร์เนลด้วย Bazel (Kleaf) แทนที่ build.sh
หากต้องการสร้างโมดูลของ virtual_device
ให้รัน:
tools/bazel build //common-modules/virtual-device:virtual_device_x86_64_dist
หากต้องการสร้างการแจกจ่าย ให้รัน:
tools/bazel run //common-modules/virtual-device:virtual_device_x86_64_dist -- --dist_dir=$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
เรียกใช้เคอร์เนล
มีหลายวิธีในการรันเคอร์เนลที่สร้างขึ้นเอง ต่อไปนี้เป็นวิธีที่ทราบกันดีว่าเหมาะสมกับสถานการณ์การพัฒนาต่างๆ
ฝังลงในบิลด์อิมเมจ 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 bootloader
fastboot boot Image.lz4-dtb
เมื่อใช้วิธีนี้ เคอร์เนลจะไม่กะพริบจริงๆ และจะไม่คงอยู่ในระหว่างการรีบูต
เรียกใช้เมล็ดบนปลาหมึก
คุณสามารถรันเคอร์เนลในสถาปัตยกรรมที่คุณเลือกได้บน อุปกรณ์ Cuttlefish
หากต้องการบู๊ตอุปกรณ์ Cuttlefish ด้วยชุด เคอร์เนลอาร์ติแฟกต์ เฉพาะ ให้รันคำสั่ง cvd start
โดยมีเคอร์เนลเป้าหมายเป็นพารามิเตอร์ คำสั่งตัวอย่างต่อไปนี้ใช้สิ่งประดิษฐ์เคอร์เนลสำหรับเป้าหมาย arm64 จากรายการเคอร์เนล common-android14-6.1
cvd start \
-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
สำหรับข้อมูลเพิ่มเติม โปรดดูที่ การพัฒนาเมล็ดบนปลาหมึก
ปรับแต่งการสร้างเคอร์เนล
หากต้องการปรับแต่งเคอร์เนลบิลด์สำหรับบิลด์ Kleaf โปรดดู เอกสารประกอบของ Kleaf
ปรับแต่งเคอร์เนลบิลด์ด้วย build.sh (ดั้งเดิม)
สำหรับ build/build.sh
กระบวนการสร้างและผลลัพธ์อาจได้รับอิทธิพลจากตัวแปรสภาพแวดล้อม ส่วนใหญ่เป็นทางเลือกและสาขาเคอร์เนลแต่ละสาขาควรมีการกำหนดค่าเริ่มต้นที่เหมาะสม รายการที่ใช้บ่อยที่สุดแสดงไว้ที่นี่ สำหรับรายการที่สมบูรณ์ (และเป็นปัจจุบัน) โปรดดูที่ build/build.sh
ตัวแปรสภาพแวดล้อม | คำอธิบาย | ตัวอย่าง |
---|---|---|
BUILD_CONFIG | สร้างไฟล์กำหนดค่าจากตำแหน่งที่คุณเริ่มต้นสภาพแวดล้อมการสร้าง ต้องกำหนดตำแหน่งโดยสัมพันธ์กับไดเร็กทอรีราก 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 |
การกำหนดค่าเคอร์เนลแบบกำหนดเองสำหรับบิลด์ในเครื่อง
ใน Android 14 ขึ้นไป คุณสามารถใช้ส่วน defconfig เพื่อปรับแต่งการกำหนดค่าเคอร์เนลได้ ดู เอกสารประกอบของ Kleaf เกี่ยวกับ defconfig แฟรกเมนต์
การกำหนดค่าเคอร์เนลแบบกำหนดเองสำหรับบิลด์ในเครื่องด้วยการกำหนดค่าบิลด์ (ดั้งเดิม)
ใน Android 13 และต่ำกว่า โปรดดูข้อมูลต่อไปนี้
หากคุณต้องการสลับตัวเลือกการกำหนดค่าเคอร์เนลเป็นประจำ เช่น เมื่อทำงานกับคุณสมบัติ หรือหากคุณต้องการตัวเลือกในการตั้งค่าเพื่อการพัฒนา คุณสามารถบรรลุความยืดหยุ่นดังกล่าวได้โดยคงการแก้ไขในเครื่องหรือคัดลอกการกำหนดค่าบิลด์ไว้
ตั้งค่าตัวแปร POST_DEFCONFIG_CMDS ให้เป็นคำสั่งที่ได้รับการประเมินทันทีหลังจากขั้นตอน make defconfig
ตามปกติเสร็จสิ้น เนื่องจากไฟล์ build.config
มีแหล่งที่มาในสภาพแวดล้อม build ฟังก์ชันที่กำหนดไว้ใน 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 มีเวอร์ชันเคอร์เนลที่สร้างไว้ล่วงหน้า บันทึกคอมไพล์จะแสดงเวอร์ชันที่ถูกต้องโดยเป็นส่วนหนึ่งของข้อความคอมมิต:
cd $AOSP/device/VENDOR/NAME
git 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 -- --dist_dir=$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 main คุณสามารถดาวน์โหลด ramdisk-recovery.img
build artifact จาก aosp_arm64 build บน 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
ไฟล์นั้นอยู่ในไดเร็กทอรี artifact $KERNEL_ROOT/out/$KERNEL_VERSION/dist
อิมเมจสำหรับบูตอยู่ที่ out/<kernel branch>/dist/boot.img