Linux Device Driver - newer2/Blog GitHub Wiki

设备驱动基本框架

  • 源文件 头文件+模块参数+模块功能函数+其他+模块加载函数+模块卸载函数+模块许可声明
#include <linux/init.h>
#include <linux/module.h>
#include <linux/>
#include "add_sub.h"

static long a=1;	//模块参数
static int b=1;

long add_integer(int a, int b)	//模块功能函数
{

	return a+b;
}
long sub_integer(int a, int b)
{

	return a-b;
}

static int hello_init(void)		//模块加载函数,insmod时自动调用
{
	printk(KERN_ALERT "Hello World\n");
	return 0;
}
static void hello_exit(void)	//模块卸载函数,rmmod时自动调用
{
	printk("KERN_ALTER "Hello World Exit\n");
}

module_param(a, long, S_IRUGO);	//module_param(参数名, 参数数据类型, 参数读写权限)
module_param(b, int, S_IRUGO);	//导出参数没有浮点类型,内核并不能完美的支持浮点类型,printk()也不支持浮点类型

*+++++导出功能函数以供其他模块调用+++++*
*----------
1. 在insmod module.1内核发现以ELF格式组织的module.1.symtab数据结构中有函数可以导出内核便将其中导出的功能函数的内存地址记录在内核符号表”;insmd module.2在以ELF格式组织的module.2的symtab中发现未解析的函数引用通过查询内核符号表”,将对应函数地址写入module.2的symtab中
2. 模块中定义的函数和内核中的函数冲突怎么办编译器认为模块中的函数都是私有的除非使用导出宏
+++++++++++*
EXPORT_SYMBOL(add_integer);	//导出宏
EXPORT_SYMBOL(sub_integer);

module_init(hello_init);	//模块加载函数和卸载函数的宏定义
module_exit(hello_exit);
MODULE_LICENSE("Dual BSD/GPL");		//模块许可声明
  • Makefile 正确编译内核模块条件:
  1. 不同版本的内核需要对应版本的编译工具(eg.gcc binutil)
  2. 编译的内核模块应该和测试系统对应同一内核源码
  3. 内核源码应该至少编译过一次
ifeq ($(KERNELRELEASE),)	# 检查变量KERNELRELEASE是否为空
	KERNELDIR ?= /linux-2.6.34.14/linux-2.6.34.14 
	PWD := $(shell pwd)
modules:	# Makefile的一个功能选项
	$(MAKE) -C $(KERNELDIR) M=$(PWD) modules 	# -C $(KERNELDIR)使编译器进入内核源码目录,读取其Makefile,变量KERNELRELEASE将在这里被赋值(跟踪的makefile文件可知,类似于KERNELRELEASE的许多变量,KERNELVERSION..等等将在这里被赋值并导出)
												# 编译器根据M=$(PWD)第二次进入模块所在目录,并再一次执行Makefile,此时KERNELRELEASE将是内核发布版本信息,
modules_install:
	$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install
clean:
	rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions # 删除中间文件
else
	obj-m := hello.o 	# 开始编译模块
endif
  • 模块操作
  1. insmod 模块.ko 参数1=value1 参数2=value2 #加载模块,加载后自动调用hello_init
  2. rmmod 模块.ko #卸载模块,自动调用hello_exit
  3. modprobe 可以解决模块之间依赖性的加载和删除模块命令
  4. lsmod 列出已经加载模块相关信息
  5. modinfo 查询模块作者、版权等信息
  • 模块间通信 实例

简单的字符设备驱动

⚠️ **GitHub.com Fallback** ⚠️