02、helloworld驱动实验
在学习编程的旅程中,无论是初涉C语言还是探索其他编程语言,我们往往以一句经典的“Hello, World!”作为起点,以此叩开代码世界的大门。这一简单而富有仪式感的传统,不仅象征着程序员与计算机之间的第一次对话,更承载了无数开发者对技术的热爱与追求。同样地,在驱动程序编程的领域,我们也可以延续这一传统,以“Hello, World!”作为我们的首个驱动程序,开启通往底层系统开发的奇妙之旅。
接下来,我们将着手编写第一个驱动程序——一个名为“Hello, World!”的简单驱动模块。这不仅是我们迈向驱动开发的第一步,更是理解Linux内核机制的重要起点。通过这段代码,我们将初步领略驱动程序的基本结构、加载与卸载流程,以及与内核交互的方式。准备好了吗?让我们一起开始这段充满挑战与乐趣的驱动开发之旅吧!
驱动源码:
建议目录:kernel/drivers/test/
touch hello.c
实验代码《01_helloworld》
#include <linux/module.h>
#include <linux/kernel.h>
static int __init helloworld_init(void) //驱动入口函数
{
printk("helloworld_init\r\n");//注意: 内核打印用 printk 而不是 printf
return 0;
}
static void __exit helloworld_exit(void) //驱动出口函数
{
printk("helloworld_exit\r\n");
}
module_init(helloworld_init); //告诉linux模块入口函数,加载模块代码到操作系统
module_exit(helloworld_exit); //卸载
MODULE_LICENSE("GPL v2"); //同意 GPL 开源协议
MODULE_VERSION("1.0"); //驱动的版本
MODULE_DESCRIPTION("helloworld Driver"); //lsmod
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
配套makefile:
export ARCH=arm64
export CROSS_COMPILE=/home/book/rk/tspi/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-
obj-m +=hello.o #此处要和你的驱动源文件同名
KDIR := /home/book/rk/tspi/kernel #这里是你的内核目录
PWD ?= $(shell pwd)
all:
make -C $(KDIR) M=$(PWD) modules #make#操作
clean:
make -C $(KDIR) M=$(PWD) clean #make clean操作
2
3
4
5
6
7
8
9
CROSS_COMPILE 以自己的SDK路径为准 ,上图中我的SDK源码放在/home/book/rk/tspi目录
这段看似简洁的helloworld驱动代码,实则蕴藏着驱动开发的核心框架与逻辑。尽管其外表简单,但内在却包含了驱动开发所需的基本要素。接下来,我们将深入探讨这些构成部分。
adb push E:\tspi\hello.ko /mnt/hello.ko
insmod /mnt/hello.ko
2
3
二、驱动的基本框架
Linux驱动的基本框架主要包含以下核心部分:
必须包含的组件:
- 加载函数:驱动模块被加载到内核时,这个函数会自动运行,负责初始化设备(比如分配资源、配置硬件)。
- 卸载函数:当移除驱动模块时,这个函数会执行收尾工作(比如释放资源、关闭设备)。
- 许可证声明:必须标明模块使用的许可协议(如GPL),否则系统会警告"内核被污染",表示模块来源不可信。
可选但常用的组件:
- 模块参数:允许用户在加载驱动时,通过命令行传递配置值(例如设置设备名称或调试级别)。
- 导出符号:如果需要让其他驱动调用本模块的函数或变量,就要"导出"这些接口。
- 作者信息:注明开发者联系方式或模块用途,方便后续维护或问题反馈。
简单来说,核心就是"加载时初始化、退出时清理、必须声明许可证",其他功能根据需求添加。比如调试时用参数调整设置,多个驱动协作时用导出符号共享功能,作者信息则像软件的版权声明一样起说明作用。
三、实验
第一步:
进入~/LubanCat_SDK/kernel/drivers
目录,编辑Makefile文件。
cd kernel/drivers
vim Makefile
第二步:
创建必要的文件。
touch hello.c
touch Makefile
第三步:
hello.c 源文件编程:
vim hello.c
Makefile 源文件编程:
vim Makefile
四、Makefile详细说明
Makefile是构建驱动程序的重要工具,它定义了如何编译和链接源文件。以下是一些关键点:
架构(ARCH):指定目标架构,如ARM或ARM64。
交叉编译链(CROSS_COMPILE):设置为
aarch64-linux-gnu-
。编译对象(obj-m):
m
表示编译成.ko
模块。y
表示直接编译进内核。
内核源码路径(KDIR):指向内核源码的根目录。
当前路径(PWD):通过
$(shell pwd)
动态获取。编译命令:
make -C $(KDIR) M=$(PWD) modules
清除命令:
make -C $(KDIR) M=$(PWD) clean
五、实验操作
以下步骤完成驱动的编译与加载:
- 清理旧的编译结果:
make clean
- 编译驱动:
make
- 将生成的
.ko
文件推送到设备:adb push hell.ko /mnt
- 设置文件权限:
chmod 777 /mnt/hell.ko
- 加载模块:
insmod hell.ko
- 查看已加载模块:
lsmod
- 查看日志输出效果:
dmesg