Linux内核模块

1、内核模块注册注销:
块加载函数有返回值,模块卸载函数无返回值。两者都是无参函数,加载函数用_ init修饰,卸载函数用 _exit修饰。

#define __init  __attribute__((__section__(".init.text")))
#define __exit  __atrribute__((__section__(".exit,text")))
static  int  _ _init  demo_init(void);
static  void _ _exit  demo_exit(void);

## 2、模块参数 ##
模块参数是可以从命令行传给模块的供用户在加载模块时对模块中的参数值进行更改。可以作为内核模块参数导出的类型有byte、int、uinit、short、ushort、long、ulong、charp、bool、invbool。在/sys/module/paremters下会有以参数命名的文件节点。

static  int i=0;
module_param( i , int , 0644 );

static  int arr[6] = {0};
int  len = 0;
module_param_array( arr , int , &len , 0664 );

static char* name="Hello";
module_param( name , charp , 0664 );

//当参数为字符串时,在导出参数是需要指定字符串的内部名字和外部名字。
static char innane="Hello";
module_param_string( outname , inname , sizeof( inname ) , 0664);
//总结:
a、导出参数为简单类型时,直接用module_param(参数名,类型,权限)
b、导出参数为整型数组时,参数要多一个描述数组长度的变量的地址,而且导出参数的函数的名字也多了个array:module_param_array(数组名,int,&int0664);
c、导出参数为字符串数组时函数名称改变为module_param_string,参数中多了一个字符串的外部名字:
module_param_string(outname,inname,sizeof(inname),0664);

3、内核符号:
内核的符号在/proc/kallsyms文件中可以看到内核符号以及该符号对应的内存地址。内核模块可以导出自己的符号表以供给其它模块使用:

EXPORT_SYMBLE(符号名);
EXPROT_SYMBOL_GPL(符号名)//符号名一般为函数名

4、内核模块的编译:
要正确的编译一个我们自己的内核模块其实并不简单,首先我们要准备一份内核源码,这个内核源码是我们的模块将要加载的地方。其次要保证这个内核源码是被编译过的。然后我们来写Makefile:

ifneq ($(KERNELRELEASE) , )
    mymodule-objs = xxx.o
    obj-m         =mymodule.o
else
    KEIELDIR := /lib/modules/$(shell uname -r)/build
    PWD      :=$(shell pwd)
modules:
    make  -C  $(KERNELDIR)  M=$(PWD)  modules
endif

clean:
rm -rf .tmp_versions Module.symvers modules.order .tmp_versions .*.cmd *.o *.ko *.mod.c
//书写Makefile注意事项:1、在需要修改模块的名字时使用我们当前的这个形式但是需要注意的是,“ -objs ”是与我们的“ .c ”源码所对应的;“ -obj ”是与我们模块的新名字所对应的。

内核模块Makefile分析:
首先在自己的模块中执行make之后,则进入我们自己写的Makefile中,首先判断 (KERNELRELEASE) (KERNELRELEASE)是在Linux内核源码顶层目录下定义的,所以此时这个变量是为空的。直接执行else下面的语句:KERNELDIR=Linux内核源码顶层Makefile的目录,PWD=当前Makefile所在目录。接下来看到“ modules: ”这个伪目标,此时它下面的命令无条件执行:make -C (KERNELDIR)LinuxMakefieM= (PWD)表示执行完Linux顶级目录下的Makefile之后,再回到 (PWD)Makefile (PWD)代表我们自己模块的Makefile的路径,所以在执行完Linux源码下的目录之后第二次回到的我们自己的Makefile,不同的是此时的$(KERNELRELEASE)是有值的,它代表内核发布版本信息。所以ifneq条件是成立的,继续执行下面的语句。直到此时为止,才是真正的开始编译我们自己写的模块。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值