Bad includes in linux headers

Hello,

I’ve been trying to compile a driver from source, for a PEAK systems USB->CAN adapter.
One of its dependencies hits a fault here:

./arch/arm64/include/asm/opcodes.h:5:43: fatal error: …/…/arm/include/asm/opcodes.h: No such file or directory

basically, the arm64 header includes the /arm header below, which doesn’t exist.
#include <…/…/arm/include/asm/opcodes.h>

Is there going to be a patch, or another solution to add these files?

The R27.1 kernel source does include that header. One reason this might be valid is that the ARMv8 architecture normally operates in a 64-bit mode, but includes armhf/NEON support in a compatibility mode (that mode runs ARMv7 code plus NEON).

The source code download I used is from this URL (see the “Sources” download):
[url]https://developer.nvidia.com/embedded/linux-tegra[/url]

Thanks for the heads up.

I tried downloading the source, but the closest I could find was the opcodes.h for the nios architecture:, under:

u-boot/arch/nios2/include/asm

Do you think I’m looking in the wrong place, or is there something else I should be getting? After attaining the proper source, is a simple paste sufficient to get up and running, or is there something else that I’d have to link?

Bonus background information: the driver I’m trying to compile for is a USB adaptor that’d give our boards CAN capability: Linux PCAN Driver: Overview

You should make the driver include aarch64 opcodes instead of arm opcodes.
If the driver doesn’t compile with those, then the driver requires an ARM architecture that is not available on the TX2 and thus you’d need to port/adapt it.

I’d agree the driver needs to be for aarch64, but I think he did find a bug in the opcodes.h. It gives this relative path:

../../arm/include/asm/opcodes.h

…this path attempts to include opcodes.h from 32-bit compatibility mode (arm/arm32/ARMv7 is valid on a TX2 if in compatibility mode, but I’ve never seen anyone actually use it). The problem is that the path is incorrect…resulting in breaking when it can’t find the file. The compiler doesn’t care that the file isn’t needed for this driver :P

The bug in “arch/arm64/include/asm/opcodes.h” can probably be worked around by changing line 5 from:

#include <<b>../..</b>/arm/include/asm/opcodes.h>

…to:

#include <<b>../../..</b>/arm/include/asm/opcodes.h>

Relative path was off by one, and needed to go back one more parent directory. See if correcting the 32-bit opcodes.h path lets the compile finish.

I don’t think the kernel/drivers can run in compatibility mode, just userspace?

If it’s not used, then commenting out that include line would be the safest bet to make the driver compile.
If that breaks the driver, then the file was actually needed …

I think the relative includes are a really bad habit. Instead, the build system should make sure that the necessary files are available through include paths, and the include can be done with “” quotes.

The kernel has an optional IRQ vector for compatibility mode (see “arch/arm64/kernel/entry.S”, search for “CONFIG_COMPAT”)…I’m not sure how the code from that exception level is dealt with when enabled (I’ve never looked at the handling). You may be right that it only executes in user space mode (I see el0, but not el1…but I haven’t searched very hard…there may be a case of virtualizing from another mode).

I would tend to believe that include statement of the arm64 opcodes.h header file should actually be there, but perhaps only conditionally if the CONFIG_COMPAT is true. Still, it is a bug that the include statement has an invalid file path…the relative path needs to be fixed in a future release.

Commenting out the opcodes line got us a bit further, but the current practice of linking arm64->arm headers stalled at another file:

./arch/arm64/include/asm/dma-iommu.h:2:56: fatal error: …/…/…/…/arch/arm/include/asm/dma-iommu.h: No such file or directory
#include “…/…/…/…/arch/arm/include/asm/dma-iommu.h”

On closer inspection, the standard installation for L4T doesn’t seem to have any include directory at all for the arch/arm folder. Is there a way to install these? Searching through the source package on the website that linuxdev linked did not reveal the dma-iommu.h either.

I checked “arch/arm64/include/asm/dma-iommu.h”, which in turn includes:

#include "../../../../arch/arm/include/asm/dma-iommu.h"

In this case the arm version is there and the relative path is also correct, so something else is going on. Can you verify that this file exists:

arch/arm/include/asm/dma-iommu.h

If this doesn’t exist, then you have the wrong source code. If the file does exist, then something in the environment setup is wrong (the file should be found).

Interesting, I definitely don’t have it on mine.
Did you install a header package on top of the base TX2 kit?

I only installed the kernel source itself, I’m not using the header package separately. If the header package is removing architectures which are irrelevant, then perhaps the removal mistakenly removed files needed for compatibility mode (the “arm” files can be needed by “arm64” because of this despite architecture not being “arm”). Have you installed the full kernel source somewhere, or are you going entirely from the header package?

Thanks for the tip! I got the driver compiling now, by doing a few things with the kernel sources.

  1. Ran script to get sources / install:
    apt-add-repository universe
    apt-get update
    apt-get install qt5-default pkg-config -y
    cd /usr/src
    wget http://developer.download.nvidia.com/embedded/L4T/r27_Release_v1.0/BSP/r27.1.0_sources.tbz2
    tar -xvf r27.1.0_sources.tbz2 kernel_src.tbz2
    tar -xvf kernel_src.tbz2
    cd kernel/kernel-4.4
    zcat /proc/config.gz > .config
    make xconfig

  2. Configured and built a kernel to generate a versions.h file that I needed:
    cd /usr/src/kernel/kernel-4.4
    make prepare
    make modules_prepare
    make -j6
    make modules
    make modules_install

  3. linked the version.h file to its proper location by:
    cd /usr/src/kernel/kernel-4.4/include/linux
    ln -s /usr/src/kernel/kernel-4.4/include/generated/uapi/linux/version.h

  4. redirect the driver compile process to the modified source location:
    make KERNEL_LOCATION=/usr/src/kernel/kernel-4.4

Now I have to check whether the driver itself works, but at least it compiles! Thanks @linuxdev for the useful help!