2014-09-02 79 views
7

我试图在树莓派上编译一个内核模块(我自己写了)。我正在编译目标环境。“__aeabi_ldivmod”在编译内核模块时未定义

我得到以下输出:

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.21-1.20140626git25673c3.rpfr20.armv6hl.bcm2708。
  • gcc是4.8.2。

更新

我明明没有搜索使用正确的术语。 Another search已经购买了很多参考文献,但没有解决方案。阅读他们我认为如果想为ARM编译,不应该在内核中执行任何64位分区?

回答

11

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

如果你想做64位的分割,你必须明确地做。 使用do_div()<asm/div64.h>

+0

嗨!以及如何使模数? – flav 2016-12-06 07:17:15

+3

@flav要问一个问题,请使用“提问”按钮。或者先阅读[文档](http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/include/asm-generic/div64.h)。 – 2016-12-06 07:33:50