Xây dựng 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 sẽ hướng dẫn bạn qua quá trình chọn nguồn, xây dựng 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 kernel gần đây hơn bằng cách sử dụng Repo; tạo chúng mà không cần thêm bằng cách chạy build/build.sh từ thư mục gốc của quy trình thanh toán 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 xuống các nguồn 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 repo (BRANCH) có thể được sử dụng cùng với Lệnh "repo init", xem Nhánh kernel 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 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 nhân

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

Android 13 ra mắt hạt nhân xây dựng bằng Baazel.

Để xây dựng nhân GKI cho kiến trúc aarch64, hãy xem nhánh Android Common Kernel ra mắt trước Android 13 và 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 đó, 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 --dist_dir, 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 ở Android 12 trở xuống, HOẶ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.

Để 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 thông tin 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 thông tin chi tiết về tính năng hỗ trợ Kleaf cho từng kiến trúc, hãy xem Hỗ trợ Kleaf cho thiết bị và nhân.

Tạo 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 điểm chung cùng một nhân hệ điều hành: 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

Ra mắt Android 11 GKI, tách riêng hạt nhân thành một 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 nhân hệ điều hành

Có nhiều cách để chạy một nhân hệ điều hành 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 vào 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 TARGET_PREBUILT_KERNEL biến trong khi sử dụng make bootimage (hoặc bất kỳ biến nào khác make dòng lệnh tạo hình ảnh khởi động). Biến này là được hỗ trợ bởi tất cả thiết bị khi thiết lập qua device/common/populate-new-device.sh. Ví dụ:

export TARGET_PREBUILT_KERNEL=DIST_DIR/Image.lz4-dtb

Flash và khởi động hạt nhân bằng tính năng khởi động nhanh

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 pháp này, nhân hệ điều hành sẽ không thực sự được cài đặt ROM và sẽ không tồn tại lâu dài 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.

Cách khởi động thiết bị mực nang bằng một bộ hạt nhân cụ thể cấu phần phần mềm, hãy chạy lệnh cvd start với các cấu phần phần mềm nhân hệ điều hành mục tiêu như tham số. Lệnh ví dụ sau sử dụng cấu phần phần mềm nhân cho một mục tiêu arm64 từ Tệp kê khai 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 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 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 theo các biến môi trường. Hầu hết chúng là không bắt buộc và mỗi nhánh kernel phải đi kèm với một mã cấu hình mặc định. Những công cụ thường được sử dụng nhất được liệt kê ở đây. Đối với 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ệp cấu hình bản dựng từ nơi bạn khởi chạy môi trường tạo 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 nhân hệ điều hành tuỳ chỉnh cho các bản dựng cục bộ

Trong Android 14 trở lên, bạn có thể dùng các mảnh defconfig để tuỳ chỉnh cấu hình nhân. xem Tài liệu Kleaf về mảnh defconfig.

Cấu hình 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ũ)

Trong Android 13 trở xuống, hãy xem những mục 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 sẽ được đánh giá ngay sau bước make defconfig thông thường là xong. Vì các tệp build.config được bắt nguồn từ bản dựng môi trường, các hàm được xác định trong build.config có thể được gọi như một phần của các lệnh post-defconfig.

Một ví dụ phổ biến là việc tắt tính năng tối ưu hoá thời gian liên kết (LTO) cho giao thức chéo nhân hệ điều hành trong quá trình phát triển. Mặc dù LTO có lợi cho các nhân được phát hành, thì mức hao tổn tại thời điểm xây dựng có thể là đá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 hệ điều hành đượ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 kernel từ hình ảnh hệ thống

Để xác định phiên bản hạt nhân được sử dụng trong hình ảnh hệ thống, hãy chạy lệnh sau dựa vào 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

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

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

Tạo 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, hình ảnh khởi động được xây dựng cùng với 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 -- --dist_dir=$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 các 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 liên kết đều 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 hiện tại thư mục đang làm việc).

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

Khi bạn có tệp nhị phân ramdisk và đã sao chép tệp đó vào gki-ramdisk.lz4 trong thư mục gốc thư mục của bản dựng 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.