内核模块设计

<内核模块代码>

1)内核模块内有main()函数

2)首先编写没内核模块相应的函数功能

3)内核模块的入口由一个宏(module_init(),module_exit()),来加载和卸载(实际是指明加载函数和卸载函数,这样内核才会认识)

4)头文件:<linux/init.h><linux/module.h>

 

 

例:

#include<linux/init.h>

#include<linux/modules.h>

static int __init hello_init(void)

{

pintk(KERN_WARNING“hello,word\n”);

return 0;

}

static void __exit hello_exit(void)

{

    printk(KERN_INFO“goodby,word\n”);

}

 

module_init(hello_int);

module_exit(hello_exit);

 

注意:

1)一般都会在函数头前加上static

2)和printf()函数相比,ptintk()打印信息会有一个信息的优先级别,都是以宏的形式出现,如:KERN_WARNING 和KERN_INFO

3)linux中标志为__init的函数在连接的时候都会放在".init.text"这个区段内,另外所有__init函数在.initcall.init还保存了一份函数指针,在初始化内核的时候利用这些指针调用"__init"函数,在初始化完成之后释放"init"区段。(包括".init.text"和".initcall.init")

__init和__exit都是Linux中的宏:

#define __init __attribute__((__section__(".init.text")))

#define __exit __atrribute__((__section__(".exit.text")))

<内核模块的Makefile文件>

格式:

obj-m := helloword.o

hello-objs := file1.o file2.o file3.o file4.o

KDIR= /“path of  linux kernel”(注意:实际编写的时候是没有双引号的)

all :

make -C $(KDIR)  M=$(PWD)  modules  ARCH=arm CROSS_COMPLE=arm-linux-

clean:

rm -rf  *.o  *.ko *.oder *.symvers

 

Makefile文件分析:

KDIR :用于指定内核代码位置路径

M:用于指定驱动模块代码位置

hello-objs:用于多文件的内核驱动模块

 

 

注意:在卸载内核模块的时候,必须在文件系统中的/lib/modules 目录下有指明该模块所对应的内核版本,以表明相互匹配,可以使用命令($(uname -r)),来获取内核版本

 

<带参数的内核模块>

1 #include <linux/init.h>
2 #include <linux/module.h>
3 MODULE_LICENSE("Dual BSD/GPL");
4
5 static char *book_name = "dissecting Linux Device Driver";
6 static int num = 4 000;
7
8 static int book_init(void)
9 {
10 printk(KERN_INFO " book name:%s\n",book_name);
11 printk(KERN_INFO " book num:%d\n",num);
12 return 0;
13 }
14 static void book_exit(void)
15 {
16 printk(KERN_INFO " Book module exit\n ");
17 }
18 module_init(book_init);
19 module_exit(book_exit);
20 module_param(num, int, S_IRUGO);
21 module_param(book_name, charp, S_IRUGO);
22
23 MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
24 MODULE_DESCRIPTION("A simple Module for testing module params");
25 MODULE_VERSION("V1.0");

1)声明并定义模块参数

module_param(参数名,参数类型,参数读/写权限)

2)装载模块时想用户空间向模块传递参数

insmode 模块名 参数名=参数值  (注意:参数类型可以是int short long byte uint ushort ulong charp bool )

3)实现该功能的机制

模块被装载后,会在"/sys/module"目录下出现该模块的名字的目录,当"参数读/写权限"为0的时,表示此参数不存在sysfs文件系统下对应的文件节点,如果当"参数读/写权限"不为0的时,在"sys/module"下对应的模块的名字的目录下将出现parameters目录。该目录下包含一系列的以参数名字命名的文件节点。

 

<导出符号>

1)什么是导出符号

在Linux2.6的"/proc/kallsyms"文件(存在于内存中)对应着内核符号表,他记录了符号(导出的函数或模块)以及符号所在内存中的地址。

2)怎么导出符号

EXPORT_SYMBOL(符号名);

EXPORT_SYMBOL_GPL(符号名);

注意:导出的符号可以被其他模块使用,使用之前进行声明一下即可

3)实例

1 #include <linux/init.h>
2 #include <linux/module.h>
3 MODULE_LICENSE("Dual BSD/GPL");
4
5 int add_integar(int a,int b)
6 {
7 return a+b;
8 }
9
10 int sub_integar(int a,int b)
11 {
12 return a-b;
13 }
14
15 EXPORT_SYMBOL(add_integar);
16 EXPORT_SYMBOL(sub_integar);

在"proc/kallsyms"中的结果如下

 

<wiz_tmp_tag id="wiz-table-range-border" contenteditable="false" style="display: none;">

 
 
 
 

转载于:https://www.cnblogs.com/big-devil/p/8589902.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值