linux驱动之:模块基本知识

作为驱动的开始,我们来看一看:

1. 底层函数和上层函数的不同:


app(c)
驱动模块
入口函数
main
加载函数
应用层的库(usr/lib)
内核API
运行空间
用户空间(高3G的内存)
内核空间(低1G)
释放资源
要求释放
必须释放

2.写一个模块要有的三要素:

  1. 模块许可证的声明 MODULE_LICENSE("GPL");
  2. 模块加载函数    __init 标识,或者module_init(xx)
  3. 模块卸载函数    __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文件,文件内容如下:

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. 模块编写的两种方式:

默认模式

自定义模式

linux驱动之:模块基本知识_第1张图片


5. 向模块内传参:--insmod传参

linux驱动之:模块基本知识_第2张图片

linux驱动之:模块基本知识_第3张图片

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驱动)