Yocto · Bài 7/9

Bài 7: Phát triển kernel với Yocto và recipe kernel riêng

1 lượt đọc4 phút đọc

Kernel Linux là phần lõi của mọi hệ thống Linux nhúng: nó khởi tạo phần cứng và quản lý tài nguyên. Yocto có sẵn công cụ để chọn, cấu hình và tùy biến kernel theo phần cứng của bạn. Bài này giúp bạn nắm bức tranh tổng quan về phát triển kernel trong Yocto, rồi tự viết một recipe kernel riêng trên nhánh scarthgap.

1.Tổng quan

Trong Yocto, kernel được quản lý bằng recipe như mọi phần mềm khác. Khi làm việc với kernel, bạn cần quan tâm ba thứ:

  • Mã nguồn kernel (kernel source).
  • Cấu hình kernel (kernel config, tệp .config hay defconfig).
  • Các bản vá (patch), nếu có.
Quy trình phát triển kernel trong Yocto

1.1. Recipe kernel có sẵn

Mỗi bản Yocto hỗ trợ sẵn một vài recipe kernel. Xem trong Poky:

bash
ls poky/meta/recipes-kernel/linux/

Bạn sẽ thấy các recipe như linux-yocto, linux-yocto-rt (kernel thời gian thực), linux-yocto-tiny (kernel rất nhỏ). Với nhánh scarthgap, kernel linux-yocto mặc định là dòng 6.6.

Để biết image đang dùng recipe kernel nào, xem biến PREFERRED_PROVIDER_virtual/kernel:

bash
bitbake -e core-image-minimal | grep ^PREFERRED_PROVIDER_virtual/kernel

Kết quả sẽ là PREFERRED_PROVIDER_virtual/kernel="linux-yocto". Ngoài ra, sau khi chạy QEMU, bạn gõ uname -a để xem phiên bản kernel thực tế.

1.2. Đổi sang recipe kernel khác

Thêm một dòng vào local.conf để đổi sang kernel thời gian thực:

bash
PREFERRED_PROVIDER_virtual/kernel = "linux-yocto-rt"

Kiểm tra lại bằng bitbake -e, build lại image và chạy QEMU. Lệnh uname -a sẽ cho thấy chuỗi PREEMPT_RT trong phiên bản. Chỉ cần đổi một biến là đổi cả kernel, đó là sức mạnh của việc chia theo recipe.

2.Build image với recipe kernel tự viết

Có hai cách chính để có kernel trong Yocto:

  • Dùng recipe có sẵn trong Poky, như trên.
  • Tự viết recipe kernel riêng.

Một recipe kernel tự viết thường cần:

  • Kế thừa class kernel (cung cấp mọi công cụ để build kernel).
  • Khai báo SRC_URI trỏ đến mã nguồn kernel.
  • Khai báo thư mục mã nguồn trong biến S.
  • Cung cấp tệp defconfig.
  • Các bản vá, nếu có.

2.1. Tạo thư mục recipe

Trong layer meta-helloworld (tạo ở bài trước):

bash
mkdir -p meta-helloworld/recipes-kernel/linux/files

2.2. Tạo tệp recipe

Tạo meta-helloworld/recipes-kernel/linux/custom-kernel_1.0.bb:

bash
DESCRIPTION = "Simple example to build Yocto with a custom kernel recipe"
LICENSE = "GPL-2.0-only"
LIC_FILES_CHKSUM = "file://COPYING;md5=6bc538ed5bd9a7fc9398086aedcd7e46"

inherit kernel

SRC_URI = https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.11.8.tar.xz;name=kernel \
           file://defconfig
SRC_URI[kernel.sha256sum] = "aee8a844fe152420bece70ffae8525b9b23089aa4da31fa32f30e1859bf93c3d"

S = "${WORKDIR}/linux-6.11.8"

DEPENDS += "coreutils-native"

Giải thích các dòng chính:

  • LICENSE và LIC_FILES_CHKSUM: kernel Linux dùng giấy phép GPL-2.0, tệp COPYING nằm ngay trong mã nguồn.
  • inherit kernel: kế thừa các tác vụ cấu hình, biên dịch, cài đặt kernel và module.
  • SRC_URI: địa chỉ tệp nén của kernel. Bạn lấy liên kết từ trang kernel.org. Phần ;name=kernel đặt tên cho nguồn này, để khai báo mã băm riêng ở dòng dưới.
  • SRC_URI[kernel.sha256sum]: mã băm SHA-256 của tệp tải về. Yocto bắt buộc có mã băm để đảm bảo mã nguồn không bị đổi.
  • S: thư mục mà tệp nén giải ra. Kernel 6.11.8 giải ra thư mục linux-6.11.8.

Nếu quên khai báo mã băm, BitBake sẽ dừng với lỗi No checksum specified và in sẵn dòng SRC_URI[sha256sum] = ... để bạn dán vào. Bạn cũng có thể lấy mã băm các bản kernel từ tệp sha256sums.asc trên kernel.org.

2.3. Thêm tệp defconfig

Nếu chưa có defconfig, BitBake sẽ báo lỗi khi cấu hình kernel. Với máy ảo x86 64 bit, dùng tệp x86_64_defconfig trong kho mã Linux, tại arch/x86/configs/. Đổi tên thành defconfig và đặt vào thư mục files/ cạnh recipe:

bash
meta-helloworld/recipes-kernel/linux/files/defconfig

Bạn cũng có thể giải nén kernel rồi chạy make x86_64_defconfig và chép .config thành defconfig.

2.4. Chọn recipe làm provider cho kernel

Trong build/conf/local.conf:

bash
PREFERRED_PROVIDER_virtual/kernel = "custom-kernel"

2.5. Build kernel và image

Build riêng kernel trước để bắt lỗi sớm:

bash
bitbake custom-kernel

Rồi build image:

bash
bitbake core-image-minimal

Khi xong, chạy QEMU và kiểm tra:

bash
runqemu qemux86-64 nographic
bash
root@qemux86-64:~# uname -a

Phiên bản trong kết quả phải là 6.11.8, tức là hệ thống đang chạy kernel do recipe của bạn build.

3.Mẹo khi làm việc với kernel trong Yocto

  • Dùng bitbake -c menuconfig virtual/kernel để chỉnh cấu hình kernel bằng giao diện menu, rồi bitbake -c diffconfig virtual/kernel để lấy phần thay đổi dưới dạng "config fragment" gọn nhẹ.
  • Với linux-yocto, cách chuẩn để sửa cấu hình là thêm tệp .cfg vào SRC_URI trong một bbappend, thay vì chép cả defconfig.
  • Khi sửa mã kernel, dùng devtool modify virtual/kernel như bài sau sẽ trình bày.

4.Kết luận

Bạn đã biết kernel trong Yocto gồm mã nguồn, cấu hình và bản vá; biết cách xem và đổi recipe kernel; và biết viết một recipe kernel riêng. Bài kế tiếp chúng ta sẽ thêm một kernel module helloworld vào kernel bằng devtool.