【问题标题】:WARNING: "__aeabi_uldivmod" Undefined symbol in opendla.ko警告:“__aeabi_uldivmod”opendla.ko 中未定义的符号
【发布时间】:2021-06-22 19:39:31
【问题描述】:

我正在尝试为NVDLA NVIDIA 的深度学习加速器构建内核模块驱动程序 (KMD),最后出现以下错误。 enter image description here

在对 google 进行一些研究后,我发现这是由于 kmd 中存在 64 位操作(尤其是 64 位除法)导致了错误。经过进一步调查,我发现 kmd 是为 64 位架构编写的,而我正在尝试为 32 位(ARM cortex A9)处理器编译它。网上有人建议使用-lgcc,它会解决这个问题。

任何人都可以帮助我编辑makefile 以链接链接器库 libgcc。

提前致谢。

【问题讨论】:

  • 你认为之后它会正常工作吗?
  • @0andriy 老实说我不知道​​。但是当我搜索错误“需要未知符号__aeabi_uldivmod”时,我发现一些帖子表明它需要链接到包含__aeabi_uldivmod 定义的libgcc.a。我想尝试一下,看看它是否有效,但我不熟悉makefile,这就是为什么我希望有人可以帮助将-lgcc 与makefile 链接起来。 KMD 和 makfile 的链接是here 供您参考。
  • 欢迎来到本站!通常最好将错误消息、代码等作为文本包含在问题中(在code blocks 内),而不是图像或屏幕截图。作为文本,它们更易于访问,人们可以更轻松地复制和粘贴。
  • 你需要使用#include <linux/math64.h>中的函数来做64位除法。 (来自#include <asm/div64.h> 的旧do_div() 宏仍然被一些旧代码使用,但我不建议将它用于新代码,因为该宏的行为不像普通函数。)
  • 另外,忘记使用-lgcc,因为内核不支持它。

标签: linux-device-driver embedded-linux intel-fpga


【解决方案1】:

使用 64 位除法的 Linux 内核代码应该使用#include <linux/math64.h> 提供的函数。否则,在为 32 位架构构建时,GCC 将尝试使用内核未使用的 libgcc 中的函数。

例如,div_u64 函数将 64 位无符号除数除以 32 位无符号除数并返回 64 位无符号商。 OP引用的KMD代码包含这个函数:

int64_t dla_get_time_us(void)
{
    return ktime_get_ns() / NSEC_PER_USEC;
}

添加#include <linux/math64.h>后,可以改写为使用div_u64函数如下:

int64_t dla_get_time_us(void)
{
    return div_u64(ktime_get_ns(), NSEC_PER_USEC);
}

(请注意,ktime_get_ns() 返回一个 u64(一个无符号的 64 位整数),NSEC_PER_USEC 的值是 1000,因此可以用作 32 位除数。)

代码中可能还有其他地方使用了 64 位除法,但这是我发现的第一个。

【讨论】:

  • 感谢@Ian Abbott 的回复。它真的帮了我很多。我使用 div_u64 进行除法运算 (/),它可以正常工作和编译,没有任何错误。尽管我使用#include <linux/math64.h> 作为`#include ` 给出了不存在这样的文件或目录的错误。
  • 是的,很抱歉。我会更新答案来解决这个问题。 (我在对您的问题的评论中正确,但在我的回答中输入错误!)
  • 尝试插入模块opendla时出现错误。
  • 错误:root@arria10:~# modprobe opendla [ 26.291567] opendla: loading out-of-tree module taints kernel. [ 26.298748] Probe NVDLA config nvidia,nv_small [ 26.305601] reset engine done [ 26.310481] [drm] Initialized nvdla 0.0.0 20171017 for ff200000.nvdla on minor 0 [ 26.324761] vmap allocation for size 1073745920 failed: use vmalloc=<size> to increase size [ 26.333220] NVDLA ff200000.nvdla: failed to register drm device [ 26.339171] NVDLA: probe of ff200000.nvdla failed with error -12 驱动程序应该使用 1GB 的保留内存。写在驱动代码中
  • 驱动程序代码:dma = dma_declare_coherent_memory(drm->dev, 0x40000000, 0x40000000, 0x40000000, DMA_MEMORY_EXCLUSIVE); if ((dma )) { err = -ENOMEM; goto unref; } 保留内存的设备树节点定义reserved-memory { #address-cells = <2>; #size-cells = <2>; ranges; nvdla_mem: buffer@0x40000000 { no-map ; reg = <0x0 0x40000000 0x0 0x40000000>; }; };
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-07-07
  • 1970-01-01
  • 2016-01-14
  • 1970-01-01
  • 1970-01-01
  • 2022-01-15
  • 1970-01-01
相关资源
最近更新 更多