驱动程序支持2种模式,一种是直接编译进内核有系统管理。一种是编译成内核模块,可以由开发者动态管理。
将驱动编译为内核模块
编写驱动代码
#include <linux/module.h>
#include <linux/init.h>
static int hello_init(void)
{
printk("hello world init!!!");
return 0;
}
static void hello_exit(void)
{
printk("hello world exit!!!");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("cmy");
MODULE_VERSION("v1.0");
设置arch和交叉编译工具
export ARCH=arm64
export CROSS_COMPILE=/home/chenmy/rk356x/RK356X_Android11.0/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-
ARCH 告知编译系统目标设备的 CPU 架构类型(如 ARM、ARM64、x86 等),确保生成与目标硬件兼容的指令集代码。 CROSS_COMPILE 定义交叉编译工具链的前缀(如 aarch64-linux-gnu-),编译系统自动拼接为完整命令(如 aarch64-linux-gnu-gcc)。 若未设置 ARCH:可能编译出 x86 架构代码,无法在 ARM 设备运行。 若未设置 CROSS_COMPILE:默认使用主机编译器(如 x86 的 gcc),生成错误架构的二进制文件。
编写Makefile文件
obj-m += hello_world.o
KERNEL_DIR:=/home/chenmy/rk356x/RK356X_Android11.0/kernel
PWD?=(shell pwd)
all:
make -C $(KERNEL_DIR) M=$(PWD) modules
clean:
rm -f *.ko *.mod.o *.mod.c *.symvers *.order
KERNEL_DIR表示源码kernel的绝对路径 PWD表示当前文件所在路径 make -C <目录路径> 表示切换到指定目录后执行该目录下的 Makefile 文件 M 是内核 Makefile 的变量,指定模块源码的路径(当前目录 $(PWD))
一定要正确使用空格符号,否则会导致编译脚本失效。如下:
编译成功后将.ko文件拷贝到开发板上进行测试。
加载内核模块
insmod hello_world.ko#加载内核模块
rmmod hello_world.ko#卸载内核模块
可以通过串口查看到内核打印。
查看内核模块信息。
modinfo hello_world.ko
将驱动编译进内核
Kconfig 配置系统详解
1. 基本概念与作用
功能:Kconfig 是 Linux 内核的配置系统,用于生成图形化菜单(如 make menuconfig),管理内核编译选项(如模块编译、功能开关)。 核心文件: Kconfig:定义配置选项的语法文件。 .config:用户选择的配置结果,指导内核编译。
2. 语法规则
配置项类型: bool:二选一(Y/N)。 tristate:三态(Y/N/M,支持模块化)。 string/int:字符串或整型参数。 依赖与可见性: depends on:指定依赖条件(如 depends on ARCH_RK3568)。 select:强制启用其他选项。
3. 常用指令
config hello_world
bool "Hello World support"
default y
help
hello world
生成图形化菜单中的“Network Support”子菜单。
引入其他 Kconfig:
source "drivers/charKconfig" # 加载子目录配置
4. 实际应用示例
添加新驱动配置:
1.在驱动目录创建 Kconfig 文件,定义配置项(如 config HELLO)。
.../RK356X_Android11.0/kernel/drivers/char/dev/Kconfig
config hello_world
bool "Hello World support"
default y
help
hello world
2.修改上级目录的 Kconfig,通过 source 引入新配置。
.../RK356X_Android11.0/kernel/drivers/char/Kconfig
source "drivers/char/dev/Kconfig"
3.在 Makefile 中关联配置变量(如 obj-$(CONFIG_HELLO) += hello.o)。
.../RK356X_Android11.0/kernel/drivers/char/Makefile
.../RK356X_Android11.0/kernel/drivers/char/dev/Makefile
obj-y += hello_world.o
5. 调试与验证
make menuconfig # 启动配置界面
注意:make menuconfig命令需要在kernel根目录下执行,例如:.../RK356X_Android11.0/kernel目录下执行。
make menuconfig命令执行之前需要先设置arch,需要告诉内核配置使用那种架构,防止编译为其他架构导致在arm64上无法运行。
export ARCH=arm64
配置完成后需要将.config文件内容更新到rk默认config文件中,因为rk平台在编译时是使用的默认配置文件。
可以先将默认文件进行备份处理
cp rockchip_defconfig rockchip_defconfig_bak
更新.config内容到默认config文件中
cp .config arch/arm64/configs/rockchip_defconfig
修改完成后进行内核编译
source build/envsetup.sh
lunch 55
./build.sh -AC
可以看到hello world模块已经进行编译。
将编译好的boot.img进行烧录验证
通过驱动代码打印,可以看到模块已经正常加载。