编译Android驱动程序

128 阅读2分钟

驱动程序支持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进行烧录验证

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述 通过驱动代码打印,可以看到模块已经正常加载。