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
相關文章
相關標籤/搜索