Hạt nhân xây dựng

Trang này trình bày chi tiết quá trình xây dựng hạt nhân tùy chỉnh cho thiết bị Android. Những hướng dẫn này sẽ hướng dẫn bạn trong quá trình chọn nguồn phù hợp, xây dựng hạt nhân và nhúng kết quả vào hình ảnh hệ thống được xây dựng từ Dự án mã nguồn mở Android (AOSP).

Bạn có thể lấy thêm các nguồn kernel mới hơn bằng cách sử dụng Repo ; xây dựng chúng mà không cần cấu hình thêm bằng cách chạy build/build.sh từ thư mục gốc của quá trình kiểm tra nguồn của bạn.

Tải xuống nguồn và công cụ xây dựng

Đối với các hạt nhân gần đây, hãy sử dụng repo để tải xuống nguồn, chuỗi công cụ và tập lệnh xây dựng. Một số hạt nhân (ví dụ: hạt nhân Pixel 3) yêu cầu nguồn từ nhiều kho git, trong khi những hạt nhân khác (ví dụ: hạt nhân thông thường) chỉ yêu cầu một nguồn duy nhất. Sử dụng phương pháp repo đảm bảo thiết lập thư mục nguồn chính xác.

Tải xuống các nguồn cho chi nhánh thích hợp:

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

Để biết danh sách các nhánh repo ( BRANCH ) có thể được sử dụng với lệnh `repo init` trước đó, hãy xem Các nhánh hạt nhân và hệ thống xây dựng của chúng .

Để biết chi tiết về cách tải xuống và biên dịch hạt nhân cho thiết bị Pixel, hãy xem Xây dựng hạt nhân Pixel .

Xây dựng hạt nhân

Tòa nhà với Bazel (Kleaf)

Android 13 đã giới thiệu việc xây dựng hạt nhân bằng Bazel .

Để xây dựng nhân GKI cho kiến ​​trúc aarch64, hãy kiểm tra nhánh Android Common Kernel không sớm hơn Android 13 rồi chạy lệnh sau:

tools/bazel build //common:kernel_aarch64_dist

Để tạo một bản phân phối, hãy chạy:

tools/bazel run //common:kernel_aarch64_dist -- --dist_dir=$DIST_DIR

Sau đó, nhị phân hạt nhân, mô-đun và hình ảnh tương ứng được đặt trong thư mục $DIST_DIR . Nếu --dist_dir không được chỉ định, hãy xem đầu ra của lệnh để biết vị trí của các tạo phẩm. Để biết chi tiết, hãy tham khảo tài liệu về AOSP .

Xây dựng với build.sh (cũ)

Đối với các chi nhánh ở Android 12 trở xuống, HOẶC các chi nhánh không có Kleaf:

build/build.sh

Hạt nhân nhị phân, mô-đun và hình ảnh tương ứng được đặt trong thư mục out/ BRANCH /dist .

Xây dựng mô-đun nhà cung cấp cho thiết bị ảo

Android 13 đã giới thiệu nhân xây dựng bằng Bazel (Kleaf), thay thế build.sh .

Để xây dựng các mô-đun của virtual_device , hãy chạy:

tools/bazel build //common-modules/virtual-device:virtual_device_x86_64_dist

Để tạo một bản phân phối, hãy chạy:

tools/bazel run //common-modules/virtual-device:virtual_device_x86_64_dist -- --dist_dir=$DIST_DIR

Để biết thêm chi tiết về cách xây dựng nhân Android bằng Bazel, hãy xem. Kleaf - Xây dựng hạt nhân Android bằng Bazel .

Để biết chi tiết về hỗ trợ Kleaf cho từng kiến ​​trúc, hãy xem Hỗ trợ Kleaf cho thiết bị và hạt nhân .

Xây dựng Mô-đun nhà cung cấp cho Thiết bị ảo bằng build.sh (cũ)

Trong Android 12 Mực nang và Cá vàng hội tụ nên chúng có chung một kernel: virtual_device . Để xây dựng các mô-đun của hạt nhân đó, hãy sử dụng cấu hình bản dựng này:

BUILD_CONFIG=common-modules/virtual-device/build.config.virtual_device.x86_64 build/build.sh

Android 11 đã giới thiệu GKI , phân tách hạt nhân thành hình ảnh hạt nhân do Google duy trì và các mô-đun do nhà cung cấp duy trì, được xây dựng riêng biệt.

Ví dụ này hiển thị cấu hình hình ảnh hạt nhân:

BUILD_CONFIG=common/build.config.gki.x86_64 build/build.sh

Ví dụ này hiển thị cấu hình mô-đun (Mực nang và Trình mô phỏng):

BUILD_CONFIG=common-modules/virtual-device/build.config.cuttlefish.x86_64 build/build.sh

Chạy kernel

Có nhiều cách để chạy kernel được xây dựng tùy chỉnh. Sau đây là những cách đã biết phù hợp với các kịch bản phát triển khác nhau.

Nhúng vào bản dựng hình ảnh Android

Sao chép Image.lz4-dtb vào vị trí nhị phân kernel tương ứng trong cây AOSP và xây dựng lại image khởi động.

Ngoài ra, hãy xác định biến TARGET_PREBUILT_KERNEL trong khi sử dụng make bootimage (hoặc bất kỳ dòng lệnh make nào khác để xây dựng hình ảnh khởi động). Biến này được tất cả các thiết bị hỗ trợ khi nó được thiết lập thông qua device/common/populate-new-device.sh . Ví dụ:

export TARGET_PREBUILT_KERNEL=DIST_DIR/Image.lz4-dtb

Nhấp nháy và khởi động kernel bằng fastboot

Hầu hết các thiết bị gần đây đều có tiện ích mở rộng bộ nạp khởi động để hợp lý hóa quá trình tạo và khởi động hình ảnh khởi động.

Để khởi động kernel mà không cần flash:

adb reboot bootloader
fastboot boot Image.lz4-dtb

Sử dụng phương pháp này, kernel không thực sự được flash và sẽ không tồn tại sau khi khởi động lại.

Chạy nhân trên mực nang

Bạn có thể chạy hạt nhân theo kiến ​​trúc bạn chọn trên thiết bị Mực nang .

Để khởi động một thiết bị Mực nang với một tập hợp các tạo phẩm hạt nhân cụ thể, hãy chạy lệnh cvd start với các tạo phẩm hạt nhân đích làm tham số. Lệnh ví dụ sau sử dụng các cấu phần phần mềm hạt nhân cho mục tiêu arm64 từ tệp kê khai hạt nhân 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

Để biết thêm thông tin, hãy xem Phát triển nhân trên Mực nang .

Tùy chỉnh xây dựng kernel

Để tùy chỉnh bản dựng kernel cho bản dựng Kleaf, hãy xem tài liệu Kleaf .

Tùy chỉnh bản dựng kernel bằng build.sh (cũ)

Đối với build/build.sh , quá trình và kết quả xây dựng có thể bị ảnh hưởng bởi các biến môi trường. Hầu hết chúng là tùy chọn và mỗi nhánh kernel phải có cấu hình mặc định phù hợp. Những cái được sử dụng thường xuyên nhất được liệt kê ở đây. Để biết danh sách đầy đủ (và cập nhật), hãy tham khảo build/build.sh .

Biến môi trường Sự miêu tả Ví dụ
BUILD_CONFIG Xây dựng tệp cấu hình từ nơi bạn khởi tạo môi trường xây dựng. Vị trí phải được xác định liên quan đến thư mục gốc Repo. Mặc định là build.config .
Bắt buộc đối với hạt nhân thông thường.
BUILD_CONFIG=common/build.config.gki.aarch64
CC Ghi đè trình biên dịch sẽ được sử dụng. Quay trở lại trình biên dịch mặc định được xác định bởi build.config . CC=clang
DIST_DIR Thư mục đầu ra cơ sở cho việc phân phối kernel. DIST_DIR=/path/to/my/dist
OUT_DIR Thư mục đầu ra cơ sở cho bản dựng kernel. OUT_DIR=/path/to/my/out
SKIP_DEFCONFIG Bỏ qua make defconfig SKIP_DEFCONFIG=1
SKIP_MRPROPER Bỏ qua make mrproper SKIP_MRPROPER=1

Cấu hình kernel tùy chỉnh cho các bản dựng cục bộ

Trong Android 14 trở lên, bạn có thể sử dụng các đoạn defconfig để tùy chỉnh cấu hình kernel. xem tài liệu Kleaf về các đoạn defconfig .

Cấu hình kernel tùy chỉnh cho các bản dựng cục bộ với cấu hình bản dựng (cũ)

Trong Android 13 trở xuống, hãy xem phần sau.

Nếu bạn cần thường xuyên chuyển đổi tùy chọn cấu hình kernel, chẳng hạn như khi làm việc trên một tính năng hoặc nếu bạn cần đặt một tùy chọn cho mục đích phát triển, bạn có thể đạt được tính linh hoạt đó bằng cách duy trì sửa đổi cục bộ hoặc bản sao của cấu hình bản dựng.

Đặt biến POST_DEFCONFIG_CMDS thành câu lệnh được đánh giá ngay sau khi hoàn thành bước make defconfig thông thường. Vì các tệp build.config có nguồn gốc từ môi trường xây dựng nên các hàm được xác định trong build.config có thể được gọi như một phần của lệnh post-defconfig.

Một ví dụ phổ biến là vô hiệu hóa tối ưu hóa thời gian liên kết (LTO) cho các hạt nhân chéo trong quá trình phát triển. Mặc dù LTO có lợi cho các hạt nhân được phát hành nhưng chi phí chung tại thời điểm xây dựng có thể rất đáng kể. Đoạn mã sau được thêm vào build.config cục bộ sẽ vô hiệu hóa LTO liên tục khi sử dụng 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)
}

Xác định phiên bản kernel

Bạn có thể xác định phiên bản chính xác để xây dựng từ hai nguồn: cây AOSP và hình ảnh hệ thống.

Phiên bản hạt nhân từ cây AOSP

Cây AOSP chứa các phiên bản kernel dựng sẵn. Nhật ký git hiển thị phiên bản chính xác như một phần của thông báo cam kết:

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

Nếu phiên bản kernel không được liệt kê trong nhật ký git, hãy lấy nó từ hình ảnh hệ thống, như được mô tả bên dưới.

Phiên bản hạt nhân từ hình ảnh hệ thống

Để xác định phiên bản kernel được sử dụng trong ảnh hệ thống, hãy chạy lệnh sau đối với tệp kernel:

file kernel

Đối với các tệp Image.lz4-dtb , hãy chạy:

grep -a 'Linux version' Image.lz4-dtb

Xây dựng hình ảnh khởi động

Có thể xây dựng hình ảnh khởi động bằng môi trường xây dựng kernel.

Xây dựng hình ảnh khởi động cho thiết bị bằng init_boot

Đối với các thiết bị có phân vùng init_boot , boot image được xây dựng cùng với kernel. Hình ảnh initramfs không được nhúng vào hình ảnh khởi động.

Ví dụ: với Kleaf, bạn có thể xây dựng hình ảnh khởi động GKI bằng:

tools/bazel run //common:kernel_aarch64_dist -- --dist_dir=$DIST_DIR

Với build/build.sh (cũ), bạn có thể xây dựng hình ảnh khởi động GKI bằng:

BUILD_CONFIG=common/build.config.gki.aarch64 build/build.sh

Hình ảnh khởi động GKI nằm ở $DIST_DIR .

Xây dựng hình ảnh khởi động cho thiết bị không có init_boot (cũ)

Đối với các thiết bị không có phân vùng init_boot , bạn cần có tệp nhị phân ramdisk mà bạn có thể lấy được bằng cách tải xuống hình ảnh khởi động GKI và giải nén nó. Mọi hình ảnh khởi động GKI từ bản phát hành Android được liên kết sẽ hoạt động.

tools/mkbootimg/unpack_bootimg.py --boot_img=boot-5.4-gz.img
mv $KERNEL_ROOT/out/ramdisk gki-ramdisk.lz4

Thư mục đích là thư mục cấp cao nhất của cây hạt nhân (thư mục làm việc hiện tại).

Nếu đang phát triển bằng AOSP main, bạn có thể tải xuống cấu phần phần mềm bản dựng ramdisk-recovery.img từ bản dựng aosp_arm64 trên ci.android.com và sử dụng nó làm tệp nhị phân ramdisk của bạn.

Khi bạn có một tệp nhị phân ramdisk và đã sao chép nó sang gki-ramdisk.lz4 trong thư mục gốc của bản dựng kernel, bạn có thể tạo ảnh khởi động bằng cách thực thi:

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

Nếu bạn đang làm việc với kiến ​​trúc dựa trên x86, hãy thay thế Image bằng bzImageaarch64 bằng 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

Tệp đó nằm trong thư mục tạo tác $KERNEL_ROOT/out/$KERNEL_VERSION/dist .

Hình ảnh khởi động được đặt tại out/<kernel branch>/dist/boot.img .