Linux内核模块

1 内核模块linux

  Linux内核的总体结构很是庞大,其包含的组件也很是多,若是把全部的组件都编译进内核文件,即:zImage或bzImage,但这样会导致一个问题:占用内存过多。数组

  因此就须要动态的添加某些组件,这些组件就是内核模块。特色:模块自己并不被编译到内核文件(zImage或bzImage);能够根据需求,在内核运行期间动态的安装或卸载。函数

    安装:insmodui

      insmod /home/dongry/dnw_usb.kospa

    卸载:rmmod.net

    rmmod dnw_usb设计

    查看:lsmod指针

    lsmodcode

2 内核模块的设计与编写blog

/************************************************* *file_name:helloworld.c *************************************************/ #include <linux/init.h> #include <linux/module.h>

static int hello_init(void) { printk(KERN_WARING"hello world\n"); return 0; } static void hello_exit(void) { printk(KERN_INFO"goodbye world\n"); } module_init(hello_init); module_exit(hello_init);

  printk的用法https://blog.csdn.net/eydwyz/article/details/53044863

  必要的头文件:<linux/init.h> <linux/module.h>

  module_init()内核模块的入口 即加载函数

  module_exit()内核模块的出口 即卸载函数

  当insmod安装helloworld.ko的时候module_init(hello_init)就会被调用

  当rmmod卸载helloworld.ko的时候module_exit(hello_exit)就会被调用

2.1 内核模块必要元素框图

  内核中打印用printk,应用程序用printf

/*********************************** *filename:Makefile ************************************/ obj-m := helloworld.o KDIR := /home/dongry/mini2440/mini2440 /*开发板内核代码路径*/ all: make -C $(KDIR) M=$(PWD) modules CROSS_COMPILE=arm-linux- ARCH=arm clean: rm -f *.o *.ko *.order *.symvers
/*********************************** *filename:Makefile *function:can in x86 kernel run ************************************/ obj-m := helloworld.o KDIR := /home/dongry/x86/linux-4.19.30      /*开发板内核代码路径*/ all: make -C $(KDIR) M=$(PWD) modules clean: rm -f *.o *.ko *.order *.symvers

  make含有helloworld.c和Makefile的文件获得helloworld.ko文件;若是是通过编译的x86内核后能够直接在Terminal窗口运行insmod、lsmod、rmmod;若是是通过编译的arm内核需在secure crt上连接开发板才能运行。

3 模块声明

a)MODULE_LICENSE("遵照的协议"):声明该模块遵照的许可证协议,如"GPL"、"GPL v2"

b)MODULE_AUTHOR("做者"):声明模块的做者

c)MODULE_VERSION("版本"):声明模块的版本信息

d)MODULE_DESCRIPTION("模块功能描述"):声明模块的功能

/************************************************* *file_name:helloworld.c *************************************************/ #include <linux/init.h> #include <linux/module.h> MODULE_LICENSE("GPL");  //模块声明

static int hello_init(void) { printk(KERN_WARING"hello world\n"); return 0; } static void hello_exit(void) { printk(KERN_INFO"goodbye world\n"); } module_init(hello_init); module_exit(hello_init);

4 模块参数

  咱们能够在加载内核模块的时候向其传递参数,以让同一代码达到不一样的效果。经过宏module_param指定保存模块参数的变量。模块参数用于在加载模块时传递参数给模块。

  格式:module_param(name,type,perm)

  a)name变量的名称

  b)type变量的类型,数据类型内核支持模块参数类型有:bool、invbool(bool的发转,true变为false,false变为true)、charp(char类型指针值)、int、long、short、uint、ulong、ushort、

  c)perm访问权限,常见的访问许可值一般为S_IRUGO(读权限)和S_IWUSR(写权限)。一般状况下将他们按位或

  同时咱们也能够用下面的宏声明数组:

    Module_param_array(name,type,num,perm) 

/************************************************* *file_name:helloworld.c *************************************************/ #include <linux/init.h> #include <linux/module.h> MODULE_LICENSE("GPL");  //模块声明

int a=3; charp *p; module_param(a,int,S_IRUGO | S_IWUSR);     //加载一个整型参数
module_param(P,charp,S_IRUGO | S_IWUSR);  //加载一个字符型参数

static int hello_init(void) { printk(KERN_WARING"hello world\n"); printk("a=%d\n",a); printf("p is %s\n",p); return 0; } static void hello_exit(void) { printk(KERN_INFO"goodbye world\n"); } module_init(hello_init); module_exit(hello_init);
/*结果显示*/

/*********************************************************/ #insmod helloworld.ko a=10 p=abcd hello,world! a=10 p is abcd

5 模块符号导出

  当一个模块要使用另外一个模块的函数(变量)的时候,要使用EXPORT_SYMBOL(符号名)或者EXPORT_SYMBOL_GPL(符号名)来申明。

  注:EXPORT_SYMBOL_GPL()只适用于遵循GPL协议的模块

/********************************************** *filename:add.c *********************************************/ #include <linux/init.h> #include <linux/module.h> MODULE_LICENSE("GPL"); int add(int a,int b) { return a+b; } static int add_init(void) { return 0; } static void add_exit(void) { }

EXPORT_SYMBOL(add); //能够将add导出给其余函数 module_init(add_init); module_exit(add_exit);
/************************************************* *file_name:helloworld.c *function:calling add.c *************************************************/ #include <linux/init.h> #include <linux/module.h> MODULE_LICENSE("GPL");  //模块声明

extern add(int a,int b); int a=3; charp *p; module_param(a,int,S_IRUGO | S_IWUSR);     //加载一个整型参数
module_param(P,charp,S_IRUGO | S_IWUSR);  //加载一个字符型参数

static int hello_init(void) { printk(KERN_WARING"hello world\n"); printk("a=%d\n",a); printf("p is %s\n",p); return 0; } static void hello_exit(void) { add(1,4); printk(KERN_INFO"goodbye world\n"); } module_init(hello_init); module_exit(hello_init);
/*********************************** *filename:Makefile ************************************/ obj-m := helloworld.o add.o KDIR := /home/dongry/mini2440/mini2440      /*开发板内核代码路径*/ all: make -C $(KDIR) M=$(PWD) modules CROSS_COMPILE=arm-linux- ARCH=arm clean: rm -f *.o *.ko *.order *.symvers

/*结果显示*/

/*********************************************************/
/***************先加载add.ko,后加载helloworld.ko***************/ #insmod add.ko #insmod helloworld.ko a=10 p=abcd hello,world! a=10 p is abcd
相关文章
相关标签/搜索