01_Linux最简单驱动-helloworld
Linux最简单驱动-helloworld
驱动分为四个部分:
头文件
驱动模块的入口和出口
声明信息
功能实现
第一步,包含头文件
#include <linux/init.h> 包含宏定义的头文件
#include <linux/module.h> 包含初始化加载模块的头文件
第二步,驱动模块的入口和出口
module_init();
moudule_exit();
第三步,声明模块拥有开源许可证
MODULE_LICENSE("GPL");
第四步 功能实现
static int hello_init(void)
{
printk("hello world \n");
return 0;
}
static void hello_exit(void)
{
printk("byb byb \n");
}
内核模块加载的时候打印hello world ,内核模块卸载的时候打印"byb byb
注意:内核打印函数不能用printf,因为内核没有办法使用C语言库。
代码
helloworld.c
#include<linux/init.h> //包含宏定义的头文件
#include<linux/module.h> //包含初始化加载模块的头文件
static int hello_init(void)
{
/* 内核打印函数不能用printf,因为内核没有办法使用C语言库 */
printk("hello world\n"); //内核模块加载的时候打印hello world
return 0;
}
static void hello_exit(void)
{
printk("byby\n"); //内核模块卸载的时候打印"byb byb
}
module_init(hello_init); //驱动模块的入口
module_exit(hello_exit); //驱动模块的出口
MODULE_LICENSE("GPL"); //声明模块拥有开源许可证
编译驱动
第一种方法:
把驱动编译成模块,然后使用命令把驱动加载到内核里面(makefile)
第二种方法:
直接把驱动编译到内核。
我们这里使用第一种方法
编译成模块
第一步:先写一个Makefile
#生成的中间文件的名字是helloworld.o -m:把我们的驱动给编译成模块
obj-m +=helloworld.o
#内核路径
KDIR:=/home/mzx/imx6ull/linux-imx-rel_imx_4.1.15_2.1.0_ga
#当前目录路径
PWD?=$(shell pwd)
all:
#make会切换到内核路径的环境,把当前路径下的代码给编译成模块-C:切换到内核路径
make -C $(KDIR) M=$(PWD) modules
第二步:编译驱动
编译驱动之前需要注意的问题:
1.内核源码一定要先编译通过
2.我们编译驱动模块用的内核源码一定要和我们的开发板上运行的内核镜像是同一套
3.看一下我们Ubuntu的环境是不是arm
在内核源码路径输入'make menuconfig"
是Linux/x86,不是arm
需要设置环境变量
"export ARCH=arm"修改成arm
再输入"make menuconfig"查看一下
export CROSS_COMPILE=arm-linux-gnueabihf-
make
helloworld.ko就是编译好的驱动
拷贝到nfs服务器,在开发板上运行
使用"insmod helloworld.ko"加载驱动模块
使用lsmod查看加载模块
注意,得在这个路径下使用
使用rmmod helloworld卸载驱动模块(没有.ko后缀)