Linux设备驱动开发基础一

来源:互联网 发布:linux hosts 生效 编辑:程序博客网 时间:2024/05/16 07:48

Linux设备驱动开发基础一


驱动程序是一种可以是计算机与设备进行通信的特殊程序。主要分为三类:字符设备、块设备、网络设备

1、如何加载Linux驱动到内核

  • 手工加载:使用insmod命令加载到内核
  • 通过配置驱动所在目录下的Kconfig和Makefile文件,再通过make menuconfig 进行选择配置

这两个方法,第一个是通过模块的形式可以动态地加载到内核中和从内核中卸载,后者是在移植内核之前就需要配置,也就是出厂之前配置的。

2、Linux驱动中所必须有的函数

1、头文件
#include <linux/module.h>#include <linux/init.h>
2. 模块入口函数
module_init(<模块入口函数>);

此函数是执行insmod加载驱动模块命令后首先执行的函数

3. 模块出口函数
module_exit(<模块出口函数>);

此函数是执行remod卸载驱动模块命令后首先执行的函数

4. 模块许可证的声明
MODULE_LICENSE("GPL");
5、模块参数、模块作者相关的说明可以不用加
MODULE_AUTHOR("作者");MODULE_DESCRIPTION("描述");

3、下面是Linux驱动中最简单的一个驱动

#include <linux/module.h>#include <linux/init.h>static int __init hello_init(void){    printk(KERN_WARNING "Hello,world!\n");    return 0;}static void __exit hello_exit(void){    printk(KERN_WARNING "Hello_exit!\n");}module_init(Webee210_hello_init);module_exit(Webee210_hello_exit);MODULE_LICENSE("GPL");
这么简单的驱动程序我就不解释了,在这对其中某些细节说明一下:
  1. 每个函数前面都有 static 关键字,在Linux驱动程序中,大部分函数都会冠以 static 关键字,它表示该函数只能在本文件内使用,其他文 件的函数不能调用它。
  2. __init表示此函数只在模块加载之后进行依次初始化之后就不再调用执行,__exit和这相似。注意这里是两个下划线
  3. printk函数:printk 函数共有 7 个打印等级, 默认打印等级为 4, 级别越小,表示情况越 紧急,越是要将信息打印到终端。大于 4 的等级将不会出现在串口中断,需要查看时使用 dmesg 命令查看。

4、Makefile文件

obj-m := hello.oKDIR := /home/Linux_Kernel/linux-3.8.0all:    make -C $(KDIR) M=$(PWD) modules ARCH=arm CROSS_COMPILE=arm-linux-clean:    rm -f *.ko *.o *.mod.o *.mod.c *.symvers
简要分析:此Makefile可以作为通用的,格式都是固定的,针对不同的驱动模块,只需更改目标文件
  1. obj-m:表示驱动模块需要根据目标文件构建,此处hello.o就是我们编写驱动的C程序对于的目标文件,-m表示编译成模块,最终生成ko文件
  2. KDIR:表示我们的目标平台所使用的Linux内核源代码的位置
  3. all:就是在终端执行make命令后所执行的命令行,ARCH=arm 代表架构为 arm 而不是 X86, CROSS_COMPILE=arm-linux-代表交叉编译工具为arm-linux-XXX
  4. clean:在终端执行make clean所执行的命令行,此处的作用是清除生成驱动模块是产生的其他文件

5、编译模块

make

6、模块的操作

  • insmod:加载驱动模块
  • rmmod:卸载驱动模块
  • lsmod:列出已经被加载的模块和信息
当模块加载到内核之后部分文件会发生变化
  • /proc/modules文件会增加类似hello 1064 0 - Live 0xd4c8500的语句
  • 当模块是一个真实的设备驱动时,/proc/devices文件会出现设备信息,根据出现的信息在/dev下面建立设备节点
  • /sys/module/目录下会增加模块的基本信息
0 0
原创粉丝点击