Search code examples
linux-device-driverembedded-linuxintel-fpga

WARNING: "__aeabi_uldivmod" Undefined symbol in opendla.ko


I am trying to build kernel module driver (KMD) for NVDLA NVIDIA's Deep Learning Accelerator and got the following error at the end. enter image description here

After doing some research on google I found that it is due to 64bit operations (especially 64bit division) present in the kmd that is causing the errors. After further investigation I found that the kmd was written for 64bit architecture while I am trying to compile it for 32bit (ARM cortex A9) processor. some people online have suggested to use -lgcc, which will take care the issue.

Could anyone help me in editing the makefile to link the linker library libgcc.

Thanks in advance.


Solution

  • Linux kernel code that uses 64-bit division should use the functions provided by #include <linux/math64.h>. Otherwise, when building for 32-bit architectures, GCC will attempt to use functions from libgcc which is not used by the kernel.

    For example, the div_u64 function divides a 64-bit unsigned dividend by a 32-bit unsigned divisor and returns a 64-bit unsigned quotient. The KMD code referenced by OP contains this function:

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

    After adding #include <linux/math64.h>, it can be rewritten to use the div_u64 function as follows:

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

    (Note that ktime_get_ns() returns a u64 (an unsigned 64-bit integer) and NSEC_PER_USEC has the value 1000 so can be used as a 32-bit divisor.)

    There may be other places in the code where 64-bit division is used, but that is the first one I spotted.