编译内核模块时出现“__aeabi_ldivmod未定义”的错误

9
我正在尝试在树莓派上编译一个内核模块(我自己写的),并且我是在目标环境下进行编译的。但是我得到了以下输出:
make -C /lib/modules/3.12.23-1.20140626git25673c3.rpfr20.armv6hl.bcm2708/build M=/home/harmic/horus/ppminput modules
make[1]: Entering directory `/usr/src/kernels/3.12.23-1.20140626git25673c3.rpfr20.armv6hl.bcm2708'
  CC [M]  /home/harmic/horus/ppminput/ppminput.o
  Building modules, stage 2.
  MODPOST 1 modules
WARNING: "__aeabi_ldivmod" [/home/harmic/horus/ppminput/ppminput.ko] undefined!
  CC      /home/harmic/horus/ppminput/ppminput.mod.o
  LD [M]  /home/harmic/horus/ppminput/ppminput.ko
make[1]: Leaving directory `/usr/src/kernels/3.12.23-1.20140626git25673c3.rpfr20.armv6hl.bcm2708'

确实,如果我尝试插入该模块,会得到以下信息:
insmod: ERROR: could not insert module ./ppminput.ko: Unknown symbol in module

并在系统日志中:

Sep  2 22:44:26 pidora kernel: [ 7589.354709] ppminput: Unknown symbol __aeabi_ldivmod (err 0)

在我的模块中,我已经确定了引起问题的那一行代码:
unsigned int chan_abs_val = tdiff / CHAN_SCALE;

(其中tdiff是一个s64,CHAN_SCALE是一个整数字面量)

如果我注释掉除法,问题就解决了。这是我的模块中唯一使用除法的行。

通过一些谷歌搜索,我找到了一些关于这个问题的参考资料,但没有在编译内核模块的上下文中找到。

我的makefile看起来像这样:

obj-m += ppminput.o

all:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

环境详情:

  • 树莓派运行 Pidora 2014 (Fedora 20)。
  • 内核版本为 3.12.23-1.20140626git25673c3.rpfr20.armv6hl.bcm2708。
  • gcc 版本为 4.8.2。

更新

我显然没有使用正确的术语搜索。 另一个搜索 引出了许多参考资料,但并没有解决方案。通过阅读它们,我认为如果要编译 ARM 内核,则不应在内核内执行任何 64 位除法?

1个回答

14

在大多数32位CPU上,64位除法必须使用缓慢的库函数来实现。为了防止编译器生成不明显的缓慢代码,Linux没有实现这些函数。

如果要进行64位除法运算,您必须显式地执行它们。使用<asm/div64.h>中的do_div()函数。


嗨!如何进行取模运算? - flav
3
@flav 如果您有问题,请使用“提问”按钮。或者先阅读文档 - CL.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接