Linux内核编译错误:undefined reference to `__udivdi3' & `__umoddi3'。

4
这是我得到的错误信息: http://pastebin.com/VadUW6fy
drivers/built-in.o: In function `gem_rxmac_reset':
clkdev.c:(.text+0x212238): undefined reference to `__bad_udelay'
drivers/built-in.o: In function `divide.part.4':
clkdev.c:(.text.unlikely+0x7214): undefined reference to `__udivdi3'
clkdev.c:(.text.unlikely+0x7244): undefined reference to `__umoddi3'

我谷歌搜索并找到了这个补丁:https://lkml.org/lkml/2008/4/7/82

--- a/include/linux/time.h
+++ b/include/linux/time.h
@@ -174,6 +174,10 @@ static inline void timespec_add_ns(struct timespec *a, u64 ns)
 {
        ns += a->tv_nsec;
        while(unlikely(ns >= NSEC_PER_SEC)) {
+               /* The following asm() prevents the compiler from
+                * optimising this loop into a modulo operation.  */
+               asm("" : "+r"(ns));
+
                ns -= NSEC_PER_SEC;
                a->tv_sec++;
        }

但是未能应用(可能是由于文件的新版本)。

     patching file linux/time.h
     Hunk #1 FAILED at 174.
     1 out of 1 hunk FAILED -- saving rejects to file linux/time.h.rej

令人惊讶的是,文件 time.h.rej 并不存在!



最好在这里包含问题的关键部分:不仅我们更容易阅读此处的内容而不是其他网站,而且Stack Overflow的有用性取决于其问题和答案 - 如果您的URL失效,那么这个问题对未来的其他人就没有用了。谢谢! - sarnold
那个补丁只有一行汇编代码和一个注释--你尝试过手动将该汇编代码输入到正确位置的文件中吗? - sarnold
Sarnold,但问题是新文件中没有while循环。(while(unlikely(ns> = NSEC_PER_SEC))) - inblueswithu
@sarnold,time.h文件中的函数static __always_inline void timespec_add_ns(struct timespec *a, u64 ns) { a->tv_sec += __iter_div_u64_rem(a->tv_nsec + ns, NSEC_PER_SEC, &ns); a->tv_nsec = ns; } - inblueswithu
@sarnold,感谢您对我的问题进行了更改。我以后会好好发帖的。 - inblueswithu
1个回答

1

我应该仔细阅读。补丁是针对timespec_add_ns()的,而您有gem_rxmac_reset()divide.part.4函数失败。可能与您找到的补丁无关--相反,可能是目标平台上的标准64位div/mod函数没有实现。

您是否拥有Sun GEM或Apple GMAC NIC?如果没有,您可以禁用该驱动程序并摆脱第一个错误消息。

对于第二个问题,您可能需要在clkdev.c文件中实现类似的asm技巧--当我浏览我的副本以进行重复的减法操作时,我没有发现任何一个--但也许您可以简单地窃取一个更新的clkdev.cclkdev.h来解决这个问题?(这是一个很小的机会,在git log drivers/clk/clkdev.c中只有一个条目。)


是的,你说得对。这不是为那个函数编译的。我正在为ARM编译(所以是32位-不是64位)。我会查看内核配置以删除那些GEM和NIC。 - inblueswithu
1
至于为什么Sun GEM驱动程序无法编译,是因为ARM的“udelay”函数最多只能延迟2毫秒,而该驱动程序调用了“udelay(5000)”。 - Hasturkun
嘿,我很久以前就删除了SunGEM和其他一些驱动程序,但没有进行清理。在执行$ make clean并运行$ make ARCH=${CLFS_ARCH} CROSS_COMPILE=${CLFS_TARGET}- zImage之后,内核编译得非常完美!:) 非常感谢。 - inblueswithu

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