EXPORT_SYMBOL在一个方向上导致未定义的引用,而在另一个方向上导致未定义的引用(重定位被截断)

问题描述 投票:2回答:1

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

起初,我尝试了一直用于跨平台设备驱动程序进行通信的相同方法:

  • EXPORT_SYMBOL用于驱动程序A中的相应功能
  • 将符号定义为驱动程序B中的extern并进行访问

通常像魅力一样,但这次我在链接时遇到以下错误,使用extern的平台驱动程序EXPORTing和memory.c

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

但是,如果我做相反的事情,那就是:

  • EXPORT_SYMBOL中定义和memory.c是一个函数指针
  • 将指向平台驱动程序函数的指针指定给导出的符号

... 有用!

特别...

平台驱动程序

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

memory.c:

extern void my_func(args);

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

但......

平台驱动程序

extern void (*funcptr)(args);

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

memory.c:

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

......有效!

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

它现在有效......但是为什么? :-)

c gcc linux-kernel linux-device-driver arm64
1个回答
1
投票

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

kernel symbol exporting knowledge

© www.soinside.com 2019 - 2024. All rights reserved.