加载内核模块时出现未知符号,但该符号已在内核中导出
我正在编写一个内核模块来操作 GPIO。初始化时,模块需要更改GPIO的复用。
[tld.c]
#include <mach-omap2/mux.h>
。 。 。
int open_gpio(void){
int result;
result = gpio_request_array(leds_gpios, ARRAY_SIZE(leds_gpios));
if(result != 0) {
printk("tld: cannot request gpio ports\n");
}
result = gpio_direction_output(LED_LE_PIN, 0);
omap_mux_set_gpio(OMAP_MUX_MODE7, LED_LE_PIN);
if(result != 0) {
printk("tld: cannot change GPIO muplex.\n");
gpio_free_array(leds_gpios, ARRAY_SIZE(leds_gpios));
}
return result;
}
static int tld_init(void) {
.
.
/* open gpio ports */
result = open_gpio();
.
.
}
.
module_init(tld_init);
.
函数 omap_mux_set_gpio() 在 Kernel_Source/arch/arm/mach-omap2/mux.h 中声明。所以我将它包含在源文件中。
Makefile 也是定制的。
[Makefile]
CONFIG_CROSS_COMPILE =
CROSS_COMPILE ?= $(CONFIG_CROSS_COMPILE:"%"=%)
ARCH ?= arm
SOURCE_DIR ?= /home/me/kerner_source
AS = $(CROSS_COMPILE)as
LD = $(CROSS_COMPILE)ld
CC = $(CROSS_COMPILE)gcc
CPP = $(CC) -E
AR = $(CROSS_COMPILE)ar
NM = $(CROSS_COMPILE)nm
STRIP = $(CROSS_COMPILE)strip
OBJCOPY = $(CROSS_COMPILE)objcopy
OBJDUMP = $(CROSS_COMPILE)objdump
obj-m += tld.o
ccflags-y += -I$(SOURCE_DIR)/arch/arm
all:
make ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) -C $(SOURCE_DIR) M=$(PWD) modules
clean:
rm *.o *.ko *.mod.*
我可以编译它,但有警告:
警告:“omap_mux_set_gpio”[/home/me/projects/tld.ko]未定义!
当我运行insmod时,dmesg中有错误:
tld: 未知符号 omap_mux_set_gpio (err 0)
我已通过运行以下命令检查了内核符号列表:
cat /proc/kallsyms | /proc/kallsyms | grep omap_mux_set_gpio
确实存在名为 omap_mux_set_gpio 的函数。
我认为我包含头文件的方式可能导致了问题。 mux.h 属于内核本身,但我将其视为外部内核。
正确的做法是什么?
非常感谢。
I am writing a kernel module to manipute GPIOs. In initialization, the moduel needs to change the muplex of GPIOs.
[tld.c]
#include <mach-omap2/mux.h>
.
.
.
int open_gpio(void){
int result;
result = gpio_request_array(leds_gpios, ARRAY_SIZE(leds_gpios));
if(result != 0) {
printk("tld: cannot request gpio ports\n");
}
result = gpio_direction_output(LED_LE_PIN, 0);
omap_mux_set_gpio(OMAP_MUX_MODE7, LED_LE_PIN);
if(result != 0) {
printk("tld: cannot change GPIO muplex.\n");
gpio_free_array(leds_gpios, ARRAY_SIZE(leds_gpios));
}
return result;
}
static int tld_init(void) {
.
.
/* open gpio ports */
result = open_gpio();
.
.
}
.
module_init(tld_init);
.
Function omap_mux_set_gpio() is declared in Kernel_Source/arch/arm/mach-omap2/mux.h. So I include it in the source file.
The Makefile is also customized.
[Makefile]
CONFIG_CROSS_COMPILE =
CROSS_COMPILE ?= $(CONFIG_CROSS_COMPILE:"%"=%)
ARCH ?= arm
SOURCE_DIR ?= /home/me/kerner_source
AS = $(CROSS_COMPILE)as
LD = $(CROSS_COMPILE)ld
CC = $(CROSS_COMPILE)gcc
CPP = $(CC) -E
AR = $(CROSS_COMPILE)ar
NM = $(CROSS_COMPILE)nm
STRIP = $(CROSS_COMPILE)strip
OBJCOPY = $(CROSS_COMPILE)objcopy
OBJDUMP = $(CROSS_COMPILE)objdump
obj-m += tld.o
ccflags-y += -I$(SOURCE_DIR)/arch/arm
all:
make ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) -C $(SOURCE_DIR) M=$(PWD) modules
clean:
rm *.o *.ko *.mod.*
I can get it compiled but there is warning:
WARNING: "omap_mux_set_gpio" [/home/me/projects/tld.ko] undefined!
When i run insmod, there is error in dmesg:
tld: Unknown symbol omap_mux_set_gpio (err 0)
I have checked the kernel symbol list by runing:
cat /proc/kallsyms | grep omap_mux_set_gpio
An function called omap_mux_set_gpio does exist.
I think the way I include the header file probably is causing the problem. The mux.h belongs to the kernel itself but i treat it like an external one.
What is right way to do it?
Thank you very much.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果符号未标记为
EXPORT_SYMBOL
或EXPORT_SYMBOL_GPL
,则不能在内核模块中使用它。该符号似乎没有以这种方式标记。If a symbol is not marked as
EXPORT_SYMBOL
orEXPORT_SYMBOL_GPL
, then you can not use it in kernel modules. This symbol does not appear to be marked in that way.