打印

linux驱动之:模块基本知识

[复制链接]
202|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
kaloulin|  楼主 | 2018-8-22 09:46 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
作为驱动的开始,我们来看一看:

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, 知识

使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

439

主题

448

帖子

0

粉丝