Yocto · Bài 8/9
Bài 8: Thêm helloworld kernel module trong Yocto bằng devtool
1 lượt đọc4 phút đọc
Sau khi biết dùng devtool để sửa recipe, bước tiếp theo rất tự nhiên là dùng nó để sửa chính kernel. Bài này hướng dẫn thêm một kernel module helloworld vào kernel của Yocto nhánh scarthgap, build, chạy trên QEMU và lưu thay đổi thành một bản vá nằm trong layer riêng.
1.Tạo layer chứa thay đổi kernel
Trước hết, thiết lập môi trường:
cd ~/yocto/poky
source oe-init-build-envTạo một layer mới tên meta-kernelmodule và thêm vào dự án:
bitbake-layers create-layer ../meta-kernelmodule
bitbake-layers add-layer ../meta-kernelmodule
bitbake-layers show-layersLệnh add-layer tự cập nhật conf/bblayers.conf, bạn không cần sửa tay.
2.Lấy mã nguồn kernel bằng devtool modify
devtool modify virtual/kernelvirtual/kernel là tên chung chỉ recipe kernel đang dùng, được xác định bởi biến PREFERRED_PROVIDER_virtual/kernel. Kiểm tra bằng:
bitbake -e core-image-minimal | grep ^PREFERRED_PROVIDER_virtual/kernel=Với cấu hình mặc định, kết quả là linux-yocto. Sau khi chạy devtool modify, mã nguồn kernel được đặt tại:
build/workspace/sources/linux-yocto/Đây là một kho git đầy đủ, bạn thấy các thư mục quen thuộc như arch, drivers, fs, kernel... Việc tải về có thể mất vài phút.
3.Viết kernel module helloworld
3.1. Tạo thư mục module
Đặt module trong thư mục drivers/:
cd ~/yocto/poky/build/workspace/sources/linux-yocto
mkdir drivers/helloworld3.2. Tệp mã nguồn helloworld.c
#include <linux/module.h>
#include <linux/init.h>
#define DRIVER_AUTHOR "helloworld <your@email>"
#define DRIVER_DESC "Hello world kernel module in yocto"
#define DRIVER_VERS "1.0"
static int __init hello_world_init(void)
{
printk(KERN_INFO "Hello world kernel module in yocto\n");
return 0;
}
static void __exit hello_world_exit(void)
{
printk(KERN_INFO "Goodbye helloworld kernel module in yocto\n");
}
module_init(hello_world_init);
module_exit(hello_world_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_VERSION(DRIVER_VERS);Hàm hello_world_init chạy khi module được nạp, còn hello_world_exit chạy khi gỡ module.
3.3. Tệp Kconfig
Tạo drivers/helloworld/Kconfig:
config HELLOWORLD
tristate "Hello World Kernel Module"
default y
help
A simple Hello World kernel module.Với tristate, module có thể được biên dịch cứng vào kernel (y), biên dịch riêng (m) hoặc bỏ qua (n). Dòng default y chọn biên dịch cứng, nên thông điệp sẽ xuất hiện ngay khi kernel khởi động.
3.4. Tệp Makefile
Tạo drivers/helloworld/Makefile:
obj-$(CONFIG_HELLOWORLD) += helloworld.o4.Nối module vào hệ thống build của kernel
Kernel chỉ biết đến module của bạn khi các tệp ở thư mục cha trỏ tới nó. Sửa hai tệp trong drivers/.
Thêm vào cuối drivers/Kconfig, ngay trước dòng endmenu cuối cùng:
source "drivers/helloworld/Kconfig"Thêm vào drivers/Makefile:
obj-y += helloworld/5.Build và kiểm tra
Build kernel bằng devtool, rồi build image:
devtool build linux-yocto
bitbake core-image-minimalChạy thử trên QEMU:
runqemu qemux86-64 core-image-minimal nographicĐăng nhập root, rồi tìm thông điệp của module trong nhật ký kernel:
root@qemux86-64:~# dmesg | grep Hello
[ 4.308025] Hello world kernel module in yoctoThấy dòng đó nghĩa là module đã chạy ngay khi kernel khởi động. Con số thời gian ở đầu dòng có thể khác trên máy của bạn.
6.Lưu thay đổi bằng devtool finish
Khi đã hài lòng, bạn muốn giữ lại thay đổi trong layer riêng thay vì để nó nằm trong workspace tạm.
6.1. Commit thay đổi trong kho kernel
cd ~/yocto/poky/build/workspace/sources/linux-yocto
git status
git add .
git commit -m "Learn Yocto: add helloworld kernel module"Lệnh git status sẽ cho thấy hai tệp đã sửa (drivers/Kconfig, drivers/Makefile) và thư mục mới drivers/helloworld/.
6.2. Chạy devtool finish
devtool finish linux-yocto ~/yocto/poky/meta-kernelmoduleDevtool biến commit của bạn thành một bản vá và tạo tệp bbappend trong layer:
meta-kernelmodule/
└── recipes-kernel
└── linux
├── linux-yocto
│ └── 0001-Learn-Yocto-add-helloworld-kernel-module.patch
└── linux-yocto_%.bbappendTừ giờ, bất kỳ ai dùng layer meta-kernelmodule đều có kernel kèm module helloworld, mà không cần đụng vào mã gốc của Yocto. Thư mục mã nguồn trong workspace vẫn còn, bạn có thể xóa tay nếu không cần nữa.
7.Kết luận
Bạn đã thêm một kernel module vào kernel của Yocto bằng devtool: lấy mã, viết module, nối vào hệ thống build, thử trên QEMU và lưu lại dưới dạng bản vá trong layer riêng. Cách làm này giữ cho thay đổi gọn, dễ theo dõi và dễ nâng cấp kernel về sau.
