EXPORT_SYMBOL会在一个方向上导致未定义的引用,但在另一个方向上不会导致(未重定位)

时间:2018-12-28 17:24:19

标签: c gcc linux-kernel linux-device-driver arm64

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

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

  • EXPORT_SYMBOL用于驱动程序A中的各个功能
  • 在驱动程序B中将符号定义为 extern 并访问

通常像一个超级按钮一样工作,但是这次我在使用 extern 平台驱动程序 EXPORT 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);

...有效!

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

现在可以使用...但是为什么呢? :-)

1 个答案:

答案 0 :(得分:0)

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

kernel symbol exporting knowledge