您的位置:首页 > 运维架构 > Linux

linux 模块层叠技术和多个ko的编译

2010-12-13 22:01 387 查看
驱动程序中lsmod命令实际读取的是/proc/modules文件

即与lsmod命令对应的结果是cat /proc/modules

内核中已经加载的模块的信息存在于/sys/module目录下

modprobe命令比insmod命令要强大,它在加载某模块时会同时加载该模块所依赖的其他模块

使用modprobe -r filename的方式卸载将同时其依赖的模块

modinfo 模块名命令可以获得模块的信息

modinfo hello.ko

filename: hello.ko

alias: a simplest module

description: A simple Hello World Module

author: Jimmy

license: Dual BSD/GPL

srcversion: FC20E540C350C6F733C7546

depends:

vermagic: 2.6.28-15-genericSMP mod_unload modversions 586

驱动模块参数,MODULE_PARM_DESC可以注解参数

如:

static int num = 4000;

module_param(num, int,S_IRUGO);

MODULE_PARM_DESC(myshort,"A integer");

#include <linux/init.h>

#include <linux/module.h>

MODULE_LICENSE("Dual BSD/GPL");

static char *book_name = "dissecting Linux Device Driver";

static int num = 4000;

static int param[8] = {1, 2, 3, 4, 5, 6, 7, 8};

static int param_len = 8;

static int book_init(void)

{

int i;

printk(KERN_ALERT " bookname: %s/n", book_name);

printk(KERN_ALERT " booknum: %d/n", num);

for(i = 0; i < 8; i++)

{

printk(KERN_ALERT"param[%d] = %d /n", i, param[i]);

}

return 0;

}

static void book_exit(void)

{

printk(KERN_ALERT " Bookmodule exit/n");

}

module_init(book_init);

module_exit(book_exit);

module_param(num, int, S_IRUGO);

module_param(book_name, charp, S_IRUGO);

module_param_array(param, int, ¶m_len, S_IRUGO);

MODULE_AUTHOR("Jimmy, fightingjimmy@gmail.com");

MODULE_DESCRIPTION("A simple Module for testing module params");

MODULE_VERSION("v1.0");

sudo insmod book.ko

dmesg |tail -10

[14047.901352] book name: dissecting Linux Device Driver

[14047.901366] book num: 4000

[14047.901377] param[0] = 1

[14047.901386] param[1] = 2

[14047.901388] param[2] = 3

[14047.901389] param[3] = 4

[14047.901390] param[4] = 5

[14047.901391] param[5] = 6

[14047.901392] param[6] = 7

[14047.901393] param[7] = 8

sudo rmmod book.ko

sudo insmod book.ko book_name='Hello' num=1000 param=8,7,6,5

[14298.942521] book name: Hello

[14298.942535] book num: 1000

[14298.942547] param[0] = 8

[14298.942558] param[1] = 7

[14298.942559] param[2] = 6

[14298.942560] param[3] = 5

[14298.942561] param[4] = 5

[14298.942562] param[5] = 6

[14298.942564] param[6] = 7

[14298.942565] param[7] = 8

sudo rmmod book.ko

sudo insmod book.ko book_name="Hello World" num=1000 param=8,7,6,5

insmod: error inserting 'book.ko': -1 Unknown symbol in module

dmesg |tail -10

[15097.587159] book: Unknown parameter `world'

猜想:可能是因为传入的字符串参数带有空格的原因(有遇到类似情况的请不吝赐教)

linux2.6的/proc/kallsyms文件对应着内核符号表,它记录了以及符号所在的内存地址。

EXPORT_SYMBOL(符号名);

EXPROT_SYMBOL_GPL(符号名);

module/

include/

print.h

print/

print.c

Makefile

symbol/

test.c

Makefile

/****************************************

* print.h *

*****************************************/

#ifndef PRINT_H

#define PRINT_H

void add_integer(int a, int b);

void sub_integer(int a, int b);

#endif

/****************************************

* print.c *

*****************************************/

#include <linux/init.h>

#include <linux/module.h>

#include "print.h"

MODULE_LICENSE("Dual BSD/GPL");

void add_integer(int a, int b)

{

printk(KERN_ALERT " sum:%d/n", a + b);

}

void sub_integer(int a, int b)

{

printk(KERN_ALERT " sub:%d/n", a - b);

}

EXPORT_SYMBOL(add_integer);

EXPORT_SYMBOL(sub_integer);

/****************************************

* test.c *

*****************************************/

#include <linux/init.h>

#include <linux/module.h>



#include "print.h"

MODULE_LICENSE("GPL");



static int symbol_init(void)

{

printk(KERN_ALERT " Symboltest init/n");

add_integer(10, 6);

sub_integer(10, 6);

return 0;

}



static void symbol_exit(void)

{

printk(KERN_ALERT " Symboltest exit/n");

}



module_init(symbol_init);

module_exit(symbol_exit);

print目录下的Makefile:

obj-m := print.o

KERNELDIR ?= /lib/modules/$(shell uname -r)/build

PWD := $(shell pwd)

PRINT_INC = $(obj)/../include #包含print.h头文件

EXTRA_CFLAGS += -I $(PRINT_INC)

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

.PHONY: modules modules_install clean

symbol目录下的Makefile:

obj-m := test.o

KERNELDIR ?= /lib/modules/$(shell uname -r)/build

PWD := $(shell pwd)

SYMBOL_INC = $(obj)/../include

EXTRA_CFLAGS += -I $(SYMBOL_INC)

KBUILD_EXTRA_SYMBOLS=$(obj)/../print/Module.symvers

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

.PHONY: modules modules_install clean

注意:若是Makefile文件中没有KBUILD_EXTRA_SYMBOLS=$(obj)/../print/Module.symvers

则需要将print目录下的Module.symvers拷贝到symbol目录下,这是linux
kernel 2.6.26 之后版本的bug (详细描述, 请看http://bugzilla.kernel.org/show_bug.cgi?id=12446)

分别编译insmod即可
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: