加载内核模块时出现未知符号,但该符号已在内核中导出

发布于 2025-01-02 01:07:21 字数 1933 浏览 1 评论 0原文

我正在编写一个内核模块来操作 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

孤独陪着我 2025-01-09 01:07:21

如果符号未标记为 EXPORT_SYMBOLEXPORT_SYMBOL_GPL,则不能在内核模块中使用它。该符号似乎没有以这种方式标记。

If a symbol is not marked as EXPORT_SYMBOL or EXPORT_SYMBOL_GPL, then you can not use it in kernel modules. This symbol does not appear to be marked in that way.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文