提示:文章写完后,目录可以手动生成,怎样生成可参考一侧的帮助文档
文章目录
序言
这儿给你们介绍最基本的驱动开发框架
一、编写驱动文件
主要有下边几个部份组成:
1.相关头文件
这两个头文件性感驱动开发必须包含的头文件
#include
#include
2.驱动入口&出口
static int hello_init(void)
{
printk("hello worldn");
return 0;
}
static void hello_exit(void)
{
printk("by-byn");
}
module_init(hello_init);//入口
module_exit(hello_exit);//出口
入口函数通常是主要完成平台总线的注册等操作,出口函数就是对资源的回收
3.声明
因为Linux是开源的所以须要申明账簿GPL,同时内核也提供了好多相关的宏linux驱动开发详解,给写着描述
MODULE_LICENSE("GPL");//这个是必须要写的,不然编译会有问题
MODULE_AUTHOR("ljm");//作者
MODULE_DESCRIPTION("这是一个基本的驱动框架");
完整代码
#include
#include
static int hello_init(void)
{
printk("hello worldn");
return 0;
}
static void hello_exit(void)
{
printk("by-byn");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("ljm");
二、编译驱动的形式
我们编译驱动有两种形式,一种是和内核一起编译,另一种是编译成内核模块,这两种有哪些区别:
和内核一起编译:
对于和内核一起编译来说,是直接把驱动文件添加到内核源码的driver目录下的某一目录下,然后和内核一起编译,这中方法适宜我们完成驱动调试好以后
编译成内核模块:
对于编译成内核模块来说,是没有这些要求,我们可以把驱动置于任何地方,可以单独编译成模块即带有.ko的文件,然后我们再使用命令insmodxxx.ko来加载驱动即可,优点就是我们不须要的话可以直接使用命令rmmodxxx.ko卸载掉,而不须要再去更改编译内核,可以看出这些方法适宜我们在驱动开发时使用,适宜我们调试,节约时间。
三、编译驱动
下边使用前面介绍的两种方法来演示一下怎样编译驱动:
1.和内核一起编译:
步入到内核源码目录下的如下目录:
drivers/misc
1)添加驱动文件,这个文件就是我们上面写好的文件
2)更改Makefile文件(也是在该目录下)
这个配置就是告诉makefile文件要把hellmodule.c编译
补充:这儿不仅这些配置外还可以根据下边做法配置:
悉心的同学可能注意到自己添加的哪部份为何是obj-y而他人是obj-$(变量),如下:
这儿解释一下,-y表示默认编译到内核中linux驱动开发详解,而obj-¥(变量)表示要不要编译,编译成哪些状态由这个变量决定,这么问题来了,这个变量又是哪来的,在那里设置?这个问题也就是要说的第二种配置:
还是和上面一样,把hellomodule.c拷贝到drivers/misc目录下
(也可以在misc下新建一个目录给自己的驱动,不过须要在自己驱动文件同级目录下写Kconfig,Makefile,还有更改misc的Kconfig文件添加自己Kconfig的路径下边不介绍这些)
更改Makefile文件
表示告诉makefil文件hellomodule.c要不要编译redhat linux 9.0,编译成哪些状态(模块或则和内核一起编译)由变量CONFIG_HELLOMODULE决定
变量CONFIG_HELLOMODULE要根据下边决定
更改Kconfig文件:
具体意思如下:
config HELLOMODULE //变量,如果我们选择编译到内核相当于*,模块相当于m,不编译就空 ,图形配置决定,后面会说
tristate "HELLOMODULE" //表示该驱动有三态,* M 空
default n 默认不编译
help
this is my first driver. //帮助信息
图形配置该驱动
输入以下命令:
export ARCH=arm64 //导出环境变量为arm64
make rockchip_linux_defconfig //配置默认的内核配置文件,会产生.config文件,即最终的配置文件
输入以下命令步入图形配置:
make menuconfig
这儿我选择编译到内核
之后保存配置
然后退出即可
保存退出以后,输入以下命令保存配置内核文件。
make savedefconfig
输入以下命令保存到默认的配置文件中:
cp defconfig arch/arm64/configs/rockchip_linux_defconfig
之所以进行这两步,是由于我们前面使用的是瑞芯微的脚本编译内核,而脚本上面默认编译的配置文件就是rockchip_linux_defconfig雨林木风linux,所以我们得更新一下,不然看不到,由于我们的配置文件.config,并没有被这个脚本使用,其实你也可以使用直接使用make命令,并且使用这些方式编译下来的似乎还不能用
接出来前面的步骤是一样
3)重新编译内核
回到SDK的目录下输入以下命令编译
4)编译完成:
5)烧写新编译的镜像:
后面章节早已介绍了怎样烧写传送门
6)烧写完成后在并口复印中可以见到如下所示的复印:
这个复印消息就是我们驱动加载的时侯复印的消息
可以看出这儿复印消息一模一样,表示早已加载驱动成功
2.编译成驱动模块:
后面的方式中我们是将驱动和内核一起编译,而且我们每次更改驱动就要从新编译一次内核,非常费时间,所以我们常常把驱动编译成模块
1)编撰Makefile文件
KERNEL_DIR=/home/topeet/Linux/linux_sdk/kernel #内核源码路径
ARCH=arm64 #芯片架构
CROSS_COMPILE=/usr/local/arm64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu- #编译器
export ARCH CROSS_COMPILE
obj-m := hellomodule.o #编译成内核模块
all:
$(MAKE) -C $(KERNEL_DIR) M=$(CURDIR) modules
.PHONE:clean #伪命令
clean:
$(MAKE) -C $(KERNEL_DIR) M=$(CURDIR) clean
读者要根据自己的内核源码路径和编译器的路径设置
其中对于编译器,瑞芯微提供的SDK上面就有编译器,我们只须要使用这个即可
如下编撰Makefile设置:
KERNEL_DIR=/home/topeet/Linux/linux_sdk/kernel
ARCH=arm64
CROSS_COMPILE=/home/topeet/Linux/linux_sdk/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-
export ARCH CROSS_COMPILE
obj-m := hellomodule.o
all:
$(MAKE) -C $(KERNEL_DIR) M=$(CURDIR) modules
.PHONE:clean copy
clean:
$(MAKE) -C $(KERNEL_DIR) M=$(CURDIR) clean
copy:
sudo cp *.ko /home/embedfire/workdir
假如你出现如下错误,这么就说明你还没有设置好编译器的环境:
为了便捷我们之后编撰应用层的代码,我们最好把这个编译器环境导下来感兴趣的读者可以看这篇文章传送门
2).编译
把Makefile文件和驱动文件置于一起,如下:
执行以下命令:
make //编译
make clean //清除编译
其中hellomodule.ko就是我们的驱动模块
3.开发板加载驱动模块
通过网路Nfs或则其他方法把hellomodule.ko文件发给开发板,在开发板中执行以下操作:
insmod hellomodule.ko //表示加载驱动模块
rmmod hellomodule.ko //卸载模块
总结
本文从零开始搭建了驱动的编撰,编译,加载到实现,相信对于没有基础的读者会有一定的帮助,假如有帮助到你的地方清点击收藏+关注哦