作为驱动的开始,我们来看一看:
1. 底层函数和上层函数的不同:
app(c)
驱动模块
入口函数main
加载函数
库
应用层的库(usr/lib)
内核API运行空间用户空间(高3G的内存)
内核空间(低1G)
释放资源
要求释放
必须释放
2.写一个模块要有的三要素:
模块许可证的声明 MODULE_LICENSE("GPL");模块加载函数 __init 标识,或者module_init(xx)模块卸载函数 __exit 标识,或者module_exit(xxx)
-- 其他还可以有:模块的作者,描述,模块导出符号,参数等信息声明
MODULE_AUTHOR("DDD");
MODULE_DESCRIPTION("DDD");
MODULE_SUPPORTED_DEVICE("Test...");
3. 模块编译和装载的命令:在Linux端的命令如下:
insmod,将某个模块插入到加载,如果有 printk 可以用 dmesg 查看rmmod,将某个模块从内核中删除lsmod,显示所有已经被内核调入的模块modinfo,关键点是 vermagic:3.2.0-29... 是模块运行的内核版本modprobe,智能加载,如果依赖别的模块,会加载上别的模块
写了一个 .c文件,如何生成一个模块的方法:
添加一个Makefile文件,文件内容如下:
[plain] view plain copy
print?<img id="aimg_bnZso" class="zoom" width="12" height="12" file="https://code.csdn.net/assets/CODE_ico.png" border="0" alt="" /><img id="aimg_Vukng" class="zoom" width="12" height="12" file="https://code.csdn.net/assets/ico_fork.svg" border="0" alt="" />
ifeq ($(KERNELRELEASE),) KERNELDIR ?= /lib/modules/$(shell uname -r)/build #KERNELDIR ?= ~/wor_lip/linux-3.4.112 PWD := $(shell pwd) modules: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules modules_install: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install clean: rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions modules* Module* .PHONY: modules modules_install clean else obj-m := hello.o endif
其中需要改动的是:
KERNELDIR :内核所在路径,如果想要模块在开发板上运行,需要添加制作开发板上的linux内核源码所在路径,就是上边注释掉的部分,如果是要在自己的ubuntu中运行,未注释掉的部分就是。
obj-m:你要生成的xxx.ko ,就要改成 xxx.o
4. 模块编写的两种方式:默认模式
自定义模式
<img id="aimg_l5llg" class="zoom" file="http://img.blog.csdn.net/20160821195520805" lazyloadthumb="1" border="0" alt="" />
5. 向模块内传参:--insmod传参<img id="aimg_QMK6X" class="zoom" file="http://img.blog.csdn.net/20160821195719806" lazyloadthumb="1" border="0" alt="" />
<img id="aimg_O8y7h" class="zoom" file="http://img.blog.csdn.net/20160821195738040" lazyloadthumb="1" border="0" alt="" />
5.1 声明5.1.1 基本数据类型:基本数据类型包括 bool/invbool/short/int/long/uint/ushort/ulong
module_param(mystring, bool/invbool/short/int/long/uint/ushort/ulong, 0000); 声明可以从命令行取得参数,括号中的参数一次表示:变量名,变量类型,权限
0000 的介绍:
数字的大小表示的是 读写权限 , r w x,分别代表可读,可写,可执行,最大数字是 6,模块没有可执行的权限
这里还要说明的一点是,这个读写权限表示的是 /sys/modules/ 中模块的名字文件夹下边的变量名字的文件,
这里的文件可以用cat 来查看,echo A > B 来写(写的时候要先变身,su ),并且起作用
数字的位置表示的是 按从左到右 依次是 ,超级用户,用户组,。。
5.1.2 char*,...: --指针 module_param(mystring, charp, 0000);
5.1.3 array[]: --数组,传参用逗号隔开
module_param_array(array, int/.., &arr_argc, 0000);
int/..,数组中成员的数据类型
arr_argc,用于存放系统记录用户传入的数据个数
注意:
声明的数据都要进行初始化。
5.2 加载的时候传参的操作:对基本数据传参,在insmod的时候,变量名=数据,多个参数空格隔开
对数组传参,在insmod的时候,数组名=数组成员1的数据,数组成员2的参数。用的是逗号隔开
module_param
module_param_array(array, int/.., &arr_argc, 0000);
int/..,数组中成员的数据类型
arr_argc,用于存放系统记录用户传入的数据个数
注意:
声明的数据都要进行初始化。
linux, 知识 |