首页 > 解决方案 > EXPORT_SYMBOL 在一个方向上导致未定义的引用,但在另一个方向上没有(重定位被截断)

问题描述

我正在使用 aarch64 机器上的 4.9 Linux 内核,特别是mm/memory.c和自定义平台设备驱动程序。我的目标是让我的设备驱动程序将一些信息传达给源自memory.c中的函数的硬件。

起初,我尝试了与(平台)设备驱动程序通信时使用的相同方法:

通常像魅力一样工作,但是这次我在使用平台驱动程序EXPORTmemory.c使用extern进行链接时遇到了以下错误:

mm/memory.c:164:(.text+0x2a874): relocation truncated to fit: R_AARCH64_ADR_PREL_PG_HI21 against undefined symbol `my_func'

但是,如果我反其道而行之,那就是:

... 有用!

具体来说...

平台驱动:

void my_func(args){ ... };
EXPORT_SYMBOL(my_func);

内存.c:

extern void my_func(args);

...导致上述链接器错误。

但 ...

平台驱动:

extern void (*funcptr)(args);

driver_probe() {
...
funcptr = &my_func;
....
}

内存.c:

void (*funcptr)(args) = NULL;
EXPORT_SYMBOL(funcptr);

...有效!

快速的谷歌搜索暗示链接器错误与 gcc 选项 PIC/PIE 有关,但我找不到明确的答案。

它现在可以工作了……但是为什么呢?:-)

标签: cgcclinux-kernellinux-device-driverarm64

解决方案


我认为给定的图片将澄清这里的错误。模块导出的符号不能被内核使用。首先,内核不会像您所面临的那样构建给出链接器错误。

内核符号导出知识


推荐阅读