EXPORT_SYMBOL解析 (四)

2014-11-23 23:30:19 · 作者: · 浏览: 19
****************************************************************/

#include
#include
#include

static int func2(void)
{
extern int func1(void);
func1();
printk("In Func: %s...\n",__func__);
return 0;
}

static int __init hello_init(void)
{
printk("Module 2, Init!\n");
func2();
return 0;
}

static void __exit hello_exit(void)
{
printk("Module 2, Exit!\n");
}

module_init(hello_init);
module_exit(hello_exit);

MODULE_LICENSE("GPL");

/*********************************************************************************
* Copyright: (C) 2013 fulinux
* All rights reserved.
*
* Filename: mod_b.c
* Description: This file
*
* Version: 1.0.0(07/12/2013~)
* Author: fulinux
* ChangeLog: 1, Release initial version on "07/12/2013 10:29:55 AM"
*
********************************************************************************/

#include
#include
#include

static int func2(void)
{
extern int func1(void);
func1();
printk("In Func: %s...\n",__func__);
return 0;
}

static int __init hello_init(void)
{
printk("Module 2, Init!\n");
func2();
return 0;
}

static void __exit hello_exit(void)
{
printk("Module 2, Exit!\n");
}

module_init(hello_init);
module_exit(hello_exit);

MODULE_LICENSE("GPL");


在这里调用了第一个模块中的func1函数。

对应的Makefile文件:

[lingyun@localhost mod2]$ vim Makefile

[cpp]
obj-m:=mod2.o
mod2-y:=mod_b.o

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

PWD:=$(shell pwd)

modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules

modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install
clean:
rm -rf *.o *~core .depend .*.cmd *.ko *.ko.* *.mod.c .tmp_versions *odule* $(TARGET)

obj-m:=mod2.o
mod2-y:=mod_b.o

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

PWD:=$(shell pwd)

modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules

modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install
clean:
rm -rf *.o *~core .depend .*.cmd *.ko *.ko.* *.mod.c .tmp_versions *odule* $(TARGET)

[lingyun@localhost mod2]$ make
make -C /lib/modules/2.6.32-279.el6.x86_64/build M=/usr/local/src/lingyun/fulinux/export_symbol/mod2 modules
make[1]: Entering directory `/usr/src/kernels/2.6.32-279.el6.x86_64'
Building modules, stage 2.
MODPOST 1 modules
WARNING: "func1" [/usr/local/src/lingyun/fulinux/export_symbol/mod2/mod2.ko] undefined!
make[1]: Leaving directory `/usr/src/kernels/2.6.32-279.el6.x86_64'
[lingyun@localhost mod2]$


[lingyun@localhost mod2]$ sudo insmod mod2.ko
insmod: error inserting 'mod2.ko': -1 Unknown symbol in module
[lingyun@localhost mod2]$


解决上面的问题如下:

解决办法是把mod_a的Module.symvers放到mod_b的当前路径,从而编译mod_b,符号信息会自动连接进去.
或者在mod_b的makefile中使用KBUILD_EXTRA_SYMBOLS指定mod_a的Module.symvers, 如:
KBUILD_EXTRA_SYMBOLS=/mod_a/Module.symvers

编译mod_b时,搜索Module.symvers的路径是:
1, kernel source path, e.g. /usr/src/kernels/linux-2.6.28.10
2, makefile中M=所指定的路径, 它等效于变量KBUILD_EXTMOD的值
3, 变量KBUILD_EXTRA_SYMBOLS的值


此时Makefile文件如下:


[cpp]
obj-m:=mod2.o
mod2-y:=mod_b.o

KBUILD_EXTRA_SYMBOLS=~/fulinux/export_symbol/mod1/Module.symvers
KERNELDIR := /lib/modules/$(shell uname -r)/build

PWD:=$(shell pwd)

modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modul