一、开发模块框架
1),编写源代码 #include
//加载函数 static int __init hello_init(void) { printk("----- ^_^ --------%s-------\n",__FUNCTION__);
return 0; }
//卸载函数 static void __exit hello_exit(void) { printk("-----------%s-----------\n",__FUNCTION__); }
module_init(hello_init);//声明加载函数 module_exit(hello_exit);//声明卸载函数 MODULE_LICENSE("GPL");//认证 2):写Makefile 1 #指定内核源码的路径 2 KERNEL_DIR = /home/GNNUXXL/s5pv210/kernel/linux-3.0.8 3 CURENT_DIR = $(shell pwd) 4 5 all: 6 #将当前路径下的源码编译为内核模块 7 make -C $(KERNEL_DIR) M=$(CURENT_DIR) modules 8 clean: 9 #清除生成的模块文件 10 make -C $(KERNEL_DIR) M=$(CURENT_DIR) clean 11 install: 12 cp *.ko /opt/rootfs/drv_module/ 13 #指定哪个文件生成模块 14 obj-m = hello_drv.o 3):将生成的模块拷贝到开发板中 cp *.ko /opt/rootfs/drv_module/ 或者使用 make install 4)加载模块 [root@GNNUXXL /drv_module]# insmod hello_drv.ko ----- ^_^ --------hello_init------- 5)查看模块信息 root@GNNUXXL /drv_module]# lsmod hello_drv 779 0 - Live 0x7f00c000 6)卸载模块 [root@GNNUXXL /drv_module]# rmmod hello_drv -----------hello_exit----------- 二、模块传参特性 1)在加载模块时,可以进行传参,但是在编写代码时要对参数进行声明 例如: module_param(变量名,类型,权限 0644); module_param(num,int, 0644); module_param(name, charp, 0644);
[root@GNNUXXL /drv_module]# insmod hello_arg.ko -------------hello_arg_init------------ num=1001 name=bao_ma_nan [root@GNNUXXL /drv_module]# rmmod hello_arg -------------hello_arg_exit------------ [root@GNNUXXL /drv_module]# insmod hello_arg.ko num=1999 name="fansha" -------------hello_arg_init------------ num=1999 name=fansha
在加载模块时会创建一个同名文件存放相关参数 [root@GNNUXXL /drv_module]# ls -l /sys/module/hello_arg/parameters/ total 0 -rw-r--r-- 1 0 0 4096 Jan 1 02:29 name -rw-r--r-- 1 0 0 4096 Jan 1 02:29 num
2)模块调用 //被调用模块 int mysum(int a,int b) { return a+b; }
//声明mysum函数 EXPORT_SYMBOL(mysum); 在加载过程中,先加载被调用模块,后加载本身模块 [root@GNNUXXL /drv_module]# insmod mysum.ko [root@GNNUXXL /drv_module]# lsmod mysum 561 0 - Live 0x7f010000 [root@GNNUXXL /drv_module]# insmod hello_call.ko n=100 m=150 -----------hello_call_init------------- 100+150 = 250 [root@GNNUXXL /drv_module]# lsmod hello_call 1000 0 - Live 0x7f014000 mysum 561 1 hello_call, Live 0x7f010000 在卸载时,先卸载本身模块,后卸载调用模块 [root@GNNUXXL /drv_module]# rmmod hello_call ------------hello_call_exit----------- [root@GNNUXXL /drv_module]# rmmod mysum 三、一个完成驱动程序的开发 设备号由32位组成 -----------> 主设备号 -------高12位 -----------> 次设备号 -------低20位 1)申请设备号: register_chrdev(unsigned int major, const char * name, const struct file_operations * fops) 参数1: 当major=0时,主设备号为动态分配,函数返回主设备号 当major>0时,主设备号为静态分配,成功函数返回0 参数2:驱动的描述信息---->自定义 参数3:操作方法 查看设备号 cat /proc/devices [root@GNNUXXL /drv_module]# cat /proc/devices Character devices: 1 mem 256 hello_drv 2 pty 3 ttyp 4 /dev/vc/0 4 tty 4 ttyS 5 /dev/tty 5 /dev/console 5 /dev/ptmx 7 vcs 10 misc 13 input 21 sg 128 ptm 136 pts 204 ttySAC
2)创建设备节点 ----->手动创建设备节点 mknod 设备名 设备类型 主设备号 次设备号 mknod /dev/hello c 254 0 ----->自动创建设备节点 创建类 class_create(owner, name) 创建设备 register_device(char * name, unsigned long start, unsigned long len) 3)实现操作方法
相关链接
发表评论