Zalo Inbox

Quy trình phát triển Kernel trong Yocto Project


  • author-image

    devlinux

  • blog-tag yocto
  • blog-comment 0 Bình luận
  • blog-comment 216 Views
  • created-date 10 Apr, 2025
blog-image


Phát triển và tùy chỉnh kernel Linux là một trong những nhiệm vụ phức tạp nhưng thiết yếu khi làm việc với các hệ thống nhúng. Yocto Project cung cấp một quy trình có cấu trúc để quản lý, tùy chỉnh và xây dựng kernel Linux cho các thiết bị nhúng. Bài viết này sẽ hướng dẫn quy trình phát triển kernel cho Raspberry Pi Zero W sử dụng Yocto Project, với mục tiêu xây dựng image core-image-sato.

1. Tổng quan về Kernel trong Yocto

Yocto Project sử dụng các recipe đặc biệt để xây dựng kernel Linux. Các recipe này được đặt trong thư mục meta/recipes-kernel/linux/ của layer poky hoặc trong các meta-layer khác. Yocto hỗ trợ nhiều cách tiếp cận để phát triển kernel:

  • Kernel tiêu chuẩn: Sử dụng kernel từ kernel.org.
  • Kernel dành riêng cho thiết bị: Từ nhà cung cấp SoC hoặc board.
  • Kernel tùy chỉnh: Phiên bản kernel được điều chỉnh cho nhu cầu cụ thể.

2. Quy trình phát triển kernel

Để hướng dẫn chi tiết cách phát triển chúng ta sẽ lấy ví dụ thông qua việc tích hợp một kernel module đơn giản để điều khiển LED trên Raspberry Pi Zero W sử dụng Yocto Project. Module này sẽ điều khiển GPIO để bật/tắt LED được kết nối với chân GPIO27. Chúng ta sẽ tích hợp module này vào quy trình phát triển kernel và xây dựng image core-image-sato.

2.1. Cấu trúc module GPIO

Module GPIO của chúng ta có cấu trúc đơn giản:

mgpio/
├── Kconfig
├── Makefile
└── mgpio.c

2.1.1. mgpio.c

#include <linux/module.h>
#include <linux/gpio.h>

#define GPIO_NUMBER_27  27
#define LOW     0
#define HIGH    1

static int __init mgpio_driver_init(void)
{
    // Configure GPIO27 as output
    gpio_request(GPIO_NUMBER_27, "gpio_27");
    gpio_direction_output(GPIO_NUMBER_27, LOW);

    // Set GPIO27 to HIGH
    gpio_set_value(GPIO_NUMBER_27, HIGH);
    pr_info("GPIO27 set to HIGH, status: %d!\n", gpio_get_value(GPIO_NUMBER_27));

    return 0;
}

static void __exit mgpio_driver_exit(void)
{
    // Set GPIO27 to LOW before exiting
    gpio_set_value(GPIO_NUMBER_27, LOW);
    gpio_free(GPIO_NUMBER_27);
    pr_info("GPIO27 set to LOW\n");
}

module_init(mgpio_driver_init);
module_exit(mgpio_driver_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("DevLinux");
MODULE_DESCRIPTION("Interger GPIO Driver for Raspberry Pi Zero W (BCM2708)");

2.1.2. Makefile

EXTRA_CFLAGS = -Wall
obj-$(CONFIG_MGPIO) = mgpio.o

2.1.3. Kconfig

menu "mgpio device driver"

config MGPIO
    bool "mgpio device driver"
    depends on ARM
    default y if ARM
    help
        Select this option to run mgpio module.
endmenu

2.2. Thiết lập môi trường phát triển

Đầu tiên, thiết lập môi trường Yocto:

~/yocto/poky$ source oe-init-build-env

2.3. Sử dụng devtool để phát triển kernel

2.3.1. Trích xuất mã nguồn kernel hiện tại

Sử dụng devtool để trích xuất mã nguồn kernel:

~/yocto/poky/build$ devtool modify virtual/kernel

Lệnh này sẽ tạo một bản sao mã nguồn kernel tại workspace/sources/linux-raspberrypi.

2.3.2. Thêm module vào cấu trúc thư mục kernel

Tạo thư mục cho module:

~/yocto/poky/build$ cd workspace/sources/linux-raspberrypi
~/yocto/poky/build$ mkdir -p workspace/sources/linux-raspberrypi/drivers/gpio/mgpio

Sao chép các file mã nguồn vào đúng vị trí:

workspace/sources/linux-raspberrypi/drivers/mgpio/
├── Kconfig
├── Makefile
└── mgpio.c

2.3.3. Cập nhật Makefile và Kconfig của thư mục linux-raspberrypi/drivers

Chỉnh sửa linux-raspberrypi/drivers/Makefile để thêm module mới:

obj-$(CONFIG_MGPIO) += mgpio/

Chỉnh sửa linux-raspberrypi/drivers/Kconfig để thêm tham chiếu đến Kconfig của module:

source "drivers/mgpio/Kconfig"

2.3.4. Cấu hình kernel để kích hoạt module

Chỉnh sửa linux-raspberrypi/arch/arm/configs/bcmrpi_defconfig để kích hoạt module vào kernel Linux:

CONFIG_MGPIO=m

2.3.5. Tạo patch từ các thay đổi

Di chuyển vào thư mục linux-raspberrypi:

git add drivers/mgpio/
git add arch/arm/configs/bcmrpi_defconfig
git add drivers/Kconfig
git add drivers/Makefile
git commit -m "Add mgpio module for controlling LED on GPIO27"
git format-patch -1

2.3.6. Di chuyển file patch vào thư mục đã tạo

~/yocto/poky/build$ mkdir -p ../meta-devlinux/recipes-kernel/linux/linux-raspberrypi

Di chuyển file patch vào thư mục vừa tạo:

~/yocto/poky/build$ cp workspace/sources/linux-raspberrypi/0001-Add-mgpio-module-for-controlling-LED-on-GPIO27.patch ../meta-devlinux/recipes-kernel/linux/linux-raspberrypi/

2.3.7. Tạo bbappend file cho kernel

Tạo một file bbappend để mở rộng recipe kernel gốc:

~/yocto/poky/build$ vim ../meta-devlinux/recipes-kernel/linux/linux-raspberrypi_%.bbappend

Thêm nội dung sau vào file bbappend để bao gồm patch của bạn:

FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"

# Thêm patch vào SRC_URI
SRC_URI += "file://0001-Add-mgpio-module-for-controlling-LED-on-GPIO27.patch"

# Nếu bạn muốn module tự động tải khi khởi động
KERNEL_MODULE_AUTOLOAD += "mgpio"

2.3.8. Xây dựng kernel với patch đã thêm

Xây dựng lại kernel:

bitbake virtual/kernel

3. Kết luận

Bài viết này đã hướng dẫn chi tiết cách thêm file patch vào layer meta-devlinux cho Raspberry Pi Zero W kernel. Quy trình này cho phép bạn:

  • Tổ chức các patch kernel một cách có hệ thống
  • Tích hợp các thay đổi vào quy trình build Yocto
  • Dễ dàng quản lý và cập nhật các patch khi cần thiết
  • Với kiến thức này, bạn có thể phát triển và duy trì các tùy chỉnh kernel cho Raspberry Pi Zero W một cách chuyên nghiệp, đồng thời tích hợp chúng vào hệ thống Yocto của bạn một cách hiệu quả.

Hãy nhớ rằng việc sử dụng patch là một phương pháp tiêu chuẩn trong phát triển kernel với Yocto, giúp đảm bảo tính nhất quán và khả năng tái tạo của hệ thống nhúng của bạn.

author_photo
devlinux

0 Bình luận