Tạo nhân

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

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

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

Đối với các hạt nhân gần đây, hãy sử dụng repo để tải các nguồn, chuỗi công cụ và tập lệnh bản dựng xuố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 git kho lưu trữ, trong khi các kho lưu trữ khác (ví dụ: các hạt nhân chung) chỉ yêu cầu một nguồn. Việc sử dụng phương pháp repo đảm bảo một nguồn chính xác thiết lập thư mục.

Tải các nguồn xuống cho 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 kho lưu trữ (BRANCH) có thể sử dụng với lệnh `repo init` trước đó, hãy xem phần Nhánh nhân và hệ thống xây dựng của các nhánh đó.

Để biết thông tin chi tiết về cách tải và biên dịch nhân cho các thiết bị Pixel, hãy xem phần Tạo nhân Pixel.

Tạo nhân

Xây dựng bằng Bazel (Kleaf)

Android 13 đã ra mắt tính năng tạo nhân bằng Bazel.

Để tạo bản phân phối cho hạt nhân GKI cho kiến trúc aarch64, hãy xem một nhánh Hạt nhân chung của Android không sớm hơn Android 13, sau đó chạy lệnh sau:

tools/bazel run //common:kernel_aarch64_dist [-- --destdir=$DIST_DIR]

Sau đó, tệp nhị phân hạt nhân, các mô-đun và hình ảnh tương ứng được đặt trong Thư mục $DIST_DIR. Nếu bạn chưa chỉ định --destdir, hãy xem kết quả của lệnh cho vị trí của cấu phần phần mềm. Để biết thông tin chi tiết, hãy tham khảo tài liệu về AOSP (Dự án nguồn mở Android).

Dùng build.sh (cũ) để tạo bản dựng

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

build/build.sh

Tệp nhị phân hạt nhân, các 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 ra mắt hạt nhân xây dựng bằng Bazel (Kleaf), thay thế cho build.sh.

Để tạo bản phân phối cho các mô-đun của virtual_device, hãy chạy:

tools/bazel run //common-modules/virtual-device:virtual_device_x86_64_dist [-- --destdir=$DIST_DIR]

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

Để biết thông tin chi tiết về tính năng hỗ trợ Kleaf cho từng cấu trúc, hãy xem phần Hỗ trợ Kleaf cho thiết bị và hạt nhân.

Tạo các mô-đun nhà cung cấp cho thiết bị ảo bằng build.sh (cũ)

Trong Android 12, Cuttlefish và Goldfish hội tụ, vì vậy, chúng dùng chung một hạt nhân: virtual_device. Để tạo các mô-đun của nhân đó, hãy dùng bản dựng này cấu hình:

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

Android 11 đã ra mắt 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 tạo riêng biệt.

Ví dụ này cho thấy một 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 cho thấy một cấu hình mô-đun (Chim sẻ cá và Trình mô phỏng):

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

Chạy hạt nhân

Có nhiều cách để chạy một hạt nhân được tạo tuỳ chỉnh. Sau đây là những cách thức phổ biến phù hợp với nhiều tình huống phát triển.

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

Sao chép Image.lz4-dtb sang vị trí nhị phân của nhân hệ điều hành tương ứng trong cây AOSP và xây dựng lại hình ảnh 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 tạo hình ảnh khởi động). Tất cả thiết bị đều hỗ trợ biến này vì biến này đượ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

Truyền tệp ROM và khởi động hạt nhân bằng fastboot

Hầu hết các thiết bị gần đây đều có tiện ích trình tải khởi động để đơn giản hoá quy trình tạo và khởi động hình ảnh khởi động.

Cách khởi động nhân mà không cần cài đặt ROM:

adb reboot bootloader
fastboot boot Image.lz4-dtb

Khi sử dụng phương thức này, hạt nhân không thực sự được cài đặt ROM 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 các hạt nhân trong cấu trúc mà mình đã chọn trên Thiết bị cho cá mực.

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

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

Tuỳ chỉnh bản dựng nhân

Để tuỳ chỉnh các bản dựng nhân cho các bản dựng Kleaf, hãy xem Tài liệu về Kleaf.

Tuỳ chỉnh bản dựng hạt nhân bằng build.sh (cũ)

Đối với build/build.sh, quy trình xây dựng và kết quả có thể chịu ảnh hưởng của các biến môi trường. Hầu hết các cấu hình này đều không bắt buộc và mỗi nhánh nhân đều phải đi kèm với một cấu hình mặc định thích hợp. Những loại thường dùng nhất được liệt kê tại đây. Để xem danh sách đầy đủ (và mới nhất), hãy tham khảo build/build.sh.

Biến môi trường Mô tả Ví dụ
BUILD_CONFIG Tạo tệp cấu hình từ nơi bạn khởi chạy môi trường bản dựng. Vị trí phải được xác định tương ứng với gốc Repo thư mục. Giá trị mặc định là build.config.
Bắt buộc đối với các hạt nhân phổ biến.
BUILD_CONFIG=common/build.config.gki.aarch64
CC Ghi đè trình biên dịch sẽ được sử dụng. Quay lại mặc định trình biên dịch do build.config xác định. CC=clang
DIST_DIR Thư mục đầu ra cơ sở cho phân phối nhân. DIST_DIR=/path/to/my/dist
OUT_DIR Thư mục đầu ra cơ sở của bản dựng nhân. 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 hạt nhân tuỳ 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 mảnh defconfig để tuỳ chỉnh cấu hình hạt nhân. Hãy xem tài liệu về Kleaf trên các mảnh defconfig.

Cấu hình hạt nhân tuỳ chỉnh cho các bản dựng cục bộ có cấu hình bản dựng (cũ)

Trên Android 13 trở xuống, hãy xem nội dung sau.

Ví dụ: nếu bạn cần thường xuyên chuyển đổi tuỳ chọn cấu hình hạt nhân khi làm việc với một tính năng hoặc nếu bạn cần một lựa chọn để phát triển bạn có thể đạt được sự linh hoạt đó bằng cách duy trì việc sửa đổi hoặc sao chép cấu hình bản dựng.

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

Một ví dụ phổ biến là tắt tính năng tối ưu hoá thời gian liên kết (LTO) cho nhân hạt nhân trong quá trình phát triển. Mặc dù LTO có lợi cho các hạt nhân đã phát hành, nhưng chi phí hao tổn tại thời điểm tạo bản dựng có thể đáng kể. Đã thêm đoạn mã sau đây vào build.config cục bộ sẽ tắt LTO liên tục khi đang 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 các phiên bản kernel

Bạn có thể xác định đúng phiên bản cần xây dựng từ 2 nguồn: cây AOSP (Dự án nguồn mở Android) và hình ảnh hệ thống.

Phiên bản kernel từ cây AOSP (Dự án nguồn mở Android)

Cây AOSP chứa các phiên bản nhân được tạo sẵn. git nhật ký cho biết phiên bản chính xác dưới dạng 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 phiên bản đó từ hệ thống như được mô tả dưới đây.

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

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

file kernel

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

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

Tạo hình ảnh khởi động

Bạn có thể tạo hình ảnh khởi động bằng môi trường xây dựng hạt nhân.

Tạo hình ảnh khởi động cho các thiết bị có init_boot

Đối với các thiết bị có phân vùng init_boot, hình ảnh khởi động được tạo cùng với hạt nhân. Hình ảnh initramfs chưa được nhúng trong hình ảnh khởi động.

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

tools/bazel run //common:kernel_aarch64_dist [-- --destdir=$DIST_DIR]

Với build/build.sh (cũ), bạn có thể tạo 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 trong $DIST_DIR.

Tạo 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 một tệp nhị phân ramdisk mà bạn có thể lấy bằng cách tải hình ảnh khởi động GKI xuống rồi giải nén thư đó. Mọi hình ảnh khởi động GKI từ bản phát hành Android được liên kết đều 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 nhân (thư mục đang hoạt động).

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

Khi có tệp nhị phân ramdisk và đã sao chép tệp đó vào gki-ramdisk.lz4 trong thư mục gốc của bản dựng hạt nhân, bạn có thể tạo hình ả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 với bzImageaarch64x86_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 cấu phần phần mềm $KERNEL_ROOT/out/$KERNEL_VERSION/dist.

Hình ảnh khởi động nằm tại out/<kernel branch>/dist/boot.img.