สร้างเคอร์เนล

หน้านี้จะอธิบายถึงขั้นตอนการสร้างแบบกำหนดเอง เคอร์เนลสำหรับอุปกรณ์ Android เหล่านี้ ซึ่งจะแนะนำคุณผ่านขั้นตอนการเลือกโฆษณา แหล่งที่มา การสร้างเคอร์เนล และการฝังผลลัพธ์ลงในอิมเมจระบบ สร้างขึ้นจากโครงการโอเพนซอร์ส Android (AOSP)

คุณสามารถรับแหล่งที่มาของเคอร์เนลเพิ่มเติมได้โดยใช้ Repo รวมถึงสร้างได้ โดยเรียกใช้ build/build.sh จากรูทของ จุดชำระเงินต้นทาง

ดาวน์โหลดแหล่งที่มาและสร้างเครื่องมือสร้าง

สำหรับเคอร์เนลล่าสุด ให้ใช้ repo เพื่อดาวน์โหลดซอร์ส, Toolchain และสร้างสคริปต์ เคอร์เนลบางรายการ (เช่น เคอร์เนลของ Pixel 3) ต้องการแหล่งที่มาจาก Git หลายรายการ ที่เก็บ ในขณะที่ส่วนอื่นๆ (เช่น เคอร์เนลทั่วไป) ต้องการเพียง แหล่งที่มา การใช้แนวทาง repo ช่วยให้มีแหล่งที่มาที่ถูกต้อง การตั้งค่าไดเรกทอรี

ดาวน์โหลดแหล่งที่มาของสำหรับ Branch ที่เหมาะสม ดังนี้

mkdir android-kernel && cd android-kernel
repo init -u https://android.googlesource.com/kernel/manifest -b BRANCH
repo sync

สำหรับรายการ Branch ของที่เก็บ (BRANCH) ที่ใช้กับรายการก่อนหน้าได้ คำสั่ง "repo init" โปรดดู Bernel Branch และระบบบิลด์

โปรดดูรายละเอียดเกี่ยวกับการดาวน์โหลดและคอมไพล์เคอร์เนลสำหรับอุปกรณ์ Pixel ที่ การสร้าง Pixel Kernels

สร้างเคอร์เนล

สร้างด้วย Bazel (Kleaf)

Android 13 เปิดตัวเคอร์เนลการสร้างด้วย Bazel

หากต้องการสร้างเคอร์เนล GKI สำหรับสถาปัตยกรรม arch64 โปรดดูที่ สาขา Kernel ของ Android Common ที่เก่ากว่า 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 ด้วยชุดเคอร์เนลที่เฉพาะเจาะจง” อาร์ติแฟกต์ ให้เรียกใช้คำสั่ง cvd start กับอาร์ติแฟกต์ของเคอร์เนลเป้าหมายเป็น พารามิเตอร์ คำสั่งตัวอย่างต่อไปนี้ใช้อาร์ติแฟกต์ของเคอร์เนลสำหรับเป้าหมาย arm64 จาก ไฟล์ Manifest ของเคอร์เนล 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 กระบวนการบิลด์และผลลัพธ์อาจได้รับอิทธิพล ตามตัวแปรสภาพแวดล้อม ซึ่งส่วนใหญ่เป็นแบบไม่บังคับ และ Kernel Branch แต่ละรายการควรมาพร้อมกับ การกำหนดค่าเริ่มต้น แอปพลิเคชันที่ใช้บ่อยที่สุดจะแสดงรายการไว้ที่นี่ สำหรับ รายการที่ครบถ้วน (และเป็นปัจจุบัน) โปรดดู 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 ขึ้นไป คุณอาจใช้ Fragment defconfig ได้ เพื่อปรับแต่งการกำหนดค่าเคอร์เนล ดู เอกสารประกอบของ Kleaf เกี่ยวกับส่วนย่อย defconfig

การกำหนดค่าเคอร์เนลที่กำหนดเองสำหรับบิลด์ในเครื่องที่มีการกำหนดค่าบิลด์ (เดิม)

ใน Android 13 และต่ำกว่า ให้ดูข้อมูลต่อไปนี้

ตัวอย่างเช่น หากคุณต้องการเปลี่ยนตัวเลือกการกำหนดค่าเคอร์เนลเป็นประจำ ตัวอย่างเช่น เมื่อทำงานกับฟีเจอร์ หรือหากต้องการตั้งค่าตัวเลือกสำหรับการพัฒนา คุณสามารถบรรลุความยืดหยุ่นดังกล่าวได้โดยการรักษา การแก้ไขหรือสำเนาของการกำหนดค่าบิลด์

ตั้งค่าตัวแปร POST_DEFCONFIG_CMDS เป็นคำสั่งที่ ประเมินทันทีหลังจากขั้นตอน make defconfig ปกติคือ เสร็จสิ้น เนื่องจากไฟล์ build.config มาจากบิลด์ สภาพแวดล้อม ฟังก์ชันที่กำหนดไว้ใน build.config สามารถเรียกใช้ได้ เป็นส่วนหนึ่งของคำสั่งหลังการกำหนดค่า

ตัวอย่างทั่วไปคือการปิดใช้การเพิ่มประสิทธิภาพเวลาลิงก์ (LTO) สำหรับครอสแฮทช์ เคอร์เนลระหว่างการพัฒนา แม้ว่า 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 log จะแสดงเวอร์ชันที่ถูกต้องเป็นส่วนหนึ่งของข้อความคอมมิต:

cd $AOSP/device/VENDOR/NAME
git log --max-count=1

หากไม่มีเวอร์ชันเคอร์เนลในบันทึก Git ให้รับเวอร์ชันดังกล่าวจากระบบ รูปภาพ ตามที่อธิบายไว้ด้านล่าง

เวอร์ชัน Kernel จากอิมเมจของระบบ

ในการกำหนดเวอร์ชันเคอร์เนลที่ใช้ในอิมเมจระบบ ให้เรียกใช้คำสั่งต่อไปนี้ กับไฟล์เคอร์เนล:

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 หลัก คุณสามารถดาวน์โหลด ramdisk-recovery.img สร้างอาร์ติแฟกต์จาก aosp_arm64 ที่สร้างบน ci.android.com และใช้เป็นไบนารี ramdisk ของคุณ

เมื่อคุณมีไบนารี RAM และคัดลอกไปยัง 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