Error Compiling PCIe Driver

When compiling http://www.alterawiki.com/wiki/File:Linux_for_AVMM_DMA_On_Chip_Mem.tar.gz, I get error:

scripts/basic/fixdep: 1: scripts/basic/fixdep: Syntax error: “(” unexpected.

I see in post https://devtalk.nvidia.com/default/topic/957729/?comment=4951981 and https://devtalk.nvidia.com/default/topic/936880/jetson-tx1/jetson-tx1-24-1-release-need-help-with-complier-directions-can-not-complie/post/4885136/#4885136 that there should be a missing trailing quote on a string at line 234 of “drivers/base/Kconfig.” There is not.

Has anyone else run into this? If so, how did you resolve it?

I am running “Linux tegra-ubuntu 3.10.96-tegra #1 SMP PREEMPT Wed Nov 9 19:42:57 PST 2016 aarch64 aarch64 aarch64 GNU/Linux.”

The trailing quote was fixed on the most recent kernel for R24.2.1. There are still other edits which are required.

Thank you linuxdev. Can you point me to a list of the other edits?

The second URL you mentioned has that:
https://devtalk.nvidia.com/default/topic/936880/jetson-tx1/jetson-tx1-24-1-release-need-help-with-complier-directions-can-not-complie/post/4885136/#4885136

The clocks.c edit and fomit-frame-pointer edits, plus notes on compilers are there.

I tried cross-compiling R24.2.1 using both the Linaro and NVIDIA GCC compilers, but still see the same error:

scripts/basic/fixdep: 1: scripts/basic/fixdep: Syntax error: “(” unexpected.

I followed the procedure in http://developer.ridgerun.com/wiki/index.php?title=Compiling_Tegra_X1_source_code for downloading sources, building the Linaro compiler, and re-flashing my dev kit.

I obtained the pre-built NVIDIA GCC compiler from http://developer.nvidia.com/embedded/dlc/l4t-gcc-toolchain-64-bit-24-2-1 and http://developer.nvidia.com/embedded/dlc/l4t-gcc-toolchain-32-bit-24-2-1.

I edited kernel/source/arch/arm64/kernel/vdso32/Makefile and kernel/source/drivers/platform/tegra21_clock.c as described in http://developer.ridgerun.com/wiki/index.php?title=Compiling_Tegra_X1_source_code.

I’m using the make command

(MAKE) -C /lib/modules/3.10.96+/build M=(PWD)

Is this the correct procedure for building external modules on TX1?

P.S. I synced to git tag tegra-l4t-r24.2.1 for sources.

If you sync after an edit or fix it will probably remove the edit. If you follow this the clocks.c issue should go away:
https://devtalk.nvidia.com/default/topic/936880/jetson-tx1/jetson-tx1-24-1-release-need-help-with-complier-directions-can-not-complie/post/4885136/#4885136

Could you paste in the logs of the relevant failure, and perhaps one paragraph of build output prior to the failure? You can mouse highlight the code and surround it with the “code block” icon ("</>") in the upper right if the output is long (code block icon adds scrollbars to the post if the output is long).

Also, which environment variables did you set first, e.g., CROSS_COMPILE, ARCH, and CROSS32CC?

Thanks for your help linuxdev. For linaro build

# Linaro cross-compiler
export ARCH=arm64
export CROSS_COMPILE=/opt/linaro/gcc-linaro-5.3-2016.02-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-
export CROSS32CC=/opt/linaro/gcc-linaro-5.3-2016.02-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc

and for NVIDIA GCC build

# NVIDIA supplied cross-compiler
export ARCH=arm64
export CROSS_COMPILE=/home/jeff/cross-cc-tools/install-4.8.5-aarch64/bin/aarch64-unknown-linux-gnu-
export CROSS32CC=/home/jeff/cross-cc-tools/install-4.8.5-armhf/bin/arm-unknown-linux-gnueabi-gcc

I make the following edits after the sync:

Index: kernel_source/arch/arm64/kernel/vdso32/Makefile
===================================================================
--- kernel_source.orig/arch/arm64/kernel/vdso32/Makefile        2016-04-08 21:28:52.651992663 -0600
+++ kernel_source/arch/arm64/kernel/vdso32/Makefile     2016-04-11 12:20:03.377388110 -0600
@@ -11,7 +11,7 @@
 
 GCOV_PROFILE := n
 
-ccflags-y := -shared -fPIC -fno-common -fno-builtin -march=armv7-a
+ccflags-y := -shared -fPIC -fomit-frame-pointer -fno-common -fno-builtin -march=armv7-a
 ccflags-y += -nostdlib -Wl,-soname=linux-vdso32.so.1 \
                $(call cc-ldoption, -Wl$(comma)--hash-style=sysv)
 asflags-y := -D__VDSO32__ -s
Index: kernel_source/drivers/platform/tegra/tegra21_clocks.c
===================================================================
--- kernel_source.orig/drivers/platform/tegra/tegra21_clocks.c  2016-04-08 21:28:58.755992489 -0600
+++ kernel_source/drivers/platform/tegra/tegra21_clocks.c       2016-04-11 12:49:59.561337028 -0600
@@ -1062,7 +1062,7 @@
  */
 static void tegra21_cpu_clk_init(struct clk *c)
 {
-       c->state = (!is_lp_cluster() == (c->u.cpu.mode == MODE_G)) ? ON : OFF;
+       c->state = ((!is_lp_cluster()) == (c->u.cpu.mode == MODE_G)) ? ON : OFF;
 }
 
 static int tegra21_cpu_clk_enable(struct clk *c)

I am compiling the external module on the TX1 so I’ll make an additional comment of the build output from there.

Build output

ubuntu@tegra-ubuntu:~/avmm_dma_linux$ make
make -C /lib/modules/3.10.96+/build M=/home/ubuntu/avmm_dma_linux
make[1]: Entering directory '/usr/src/linux-headers-3.10.96+'
  CC [M]  /home/ubuntu/avmm_dma_linux/altera_dma.o
/home/ubuntu/avmm_dma_linux/altera_dma.c: In function ‘altera_dma_exec_cmd’:
/home/ubuntu/avmm_dma_linux/altera_dma.c:56:9: warning: implicit declaration of function ‘copy_from_user’ [-Wimplicit-function-declaration]
     if (copy_from_user (&kcmd, ucmd, sizeof(struct dma_cmd))) {
         ^
/home/ubuntu/avmm_dma_linux/altera_dma.c:129:46: warning: implicit declaration of function ‘copy_to_user’ [-Wimplicit-function-declaration]
                                          if (copy_to_user (kcmd.buf, &curr, siz
                                              ^
/home/ubuntu/avmm_dma_linux/altera_dma.c: In function ‘init_rp_mem’:
/home/ubuntu/avmm_dma_linux/altera_dma.c:272:9: warning: unused variable ‘increment_value’ [-Wunused-variable]
     u32 increment_value = 0;
         ^
/home/ubuntu/avmm_dma_linux/altera_dma.c: In function ‘rp_ep_compare’:
/home/ubuntu/avmm_dma_linux/altera_dma.c:287:9: warning: unused variable ‘count’ [-Wunused-variable]
     u32 count = 1;
         ^
/home/ubuntu/avmm_dma_linux/altera_dma.c:286:12: warning: unused variable ‘rp_tmp’ [-Wunused-variable]
     u32 j, rp_tmp, ep_tmp;
            ^
/home/ubuntu/avmm_dma_linux/altera_dma.c: In function ‘dma_test’:
/home/ubuntu/avmm_dma_linux/altera_dma.c:362:13: warning: unused variable ‘ep_tmp’ [-Wunused-variable]
 u32 rp_tmp, ep_tmp;
             ^
/home/ubuntu/avmm_dma_linux/altera_dma.c:362:5: warning: unused variable ‘rp_tmp’ [-Wunused-variable]
 u32 rp_tmp, ep_tmp;
     ^
/home/ubuntu/avmm_dma_linux/altera_dma.c:361:12: warning: unused variable ‘j’ [-Wunused-variable]
     int i, j;
            ^
/home/ubuntu/avmm_dma_linux/altera_dma.c:360:63: warning: unused variable ‘simul_write_count’ [-Wunused-variable]
     int loop_count = 0, num_loop_count = 1, simul_read_count, simul_write_count
                                                               ^
/home/ubuntu/avmm_dma_linux/altera_dma.c:360:45: warning: unused variable ‘simul_read_count’ [-Wunused-variable]
     int loop_count = 0, num_loop_count = 1, simul_read_count, simul_write_count
                                             ^
/home/ubuntu/avmm_dma_linux/altera_dma.c:360:25: warning: unused variable ‘num_loop_count’ [-Wunused-variable]
     int loop_count = 0, num_loop_count = 1, simul_read_count, simul_write_count
                         ^
/home/ubuntu/avmm_dma_linux/altera_dma.c:360:9: warning: unused variable ‘loop_count’ [-Wunused-variable]
     int loop_count = 0, num_loop_count = 1, simul_read_count, simul_write_count
         ^
/home/ubuntu/avmm_dma_linux/altera_dma.c: In function ‘altera_pci_probe’:
/home/ubuntu/avmm_dma_linux/altera_dma.c:714:14: warning: implicit declaration of function ‘kzalloc’ [-Wimplicit-function-declaration]
     bk_ptr = kzalloc(sizeof(struct altera_pcie_dma_bookkeep), GFP_KERNEL);
              ^
/home/ubuntu/avmm_dma_linux/altera_dma.c:714:12: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
     bk_ptr = kzalloc(sizeof(struct altera_pcie_dma_bookkeep), GFP_KERNEL);
            ^
/home/ubuntu/avmm_dma_linux/altera_dma.c:839:5: warning: implicit declaration of function ‘kfree’ [-Wimplicit-function-declaration]
     kfree(bk_ptr);
     ^
In file included from /home/ubuntu/avmm_dma_linux/altera_dma.c:15:0:
/home/ubuntu/avmm_dma_linux/altera_dma.c: At top level:
/home/ubuntu/avmm_dma_linux/altera_dma.h:171:12: warning: ‘rp_compare’ declared ‘static’ but never defined [-Wunused-function]
 static int rp_compare(u8 *virt_addr1, u8 *virt_addr2, u32 num_dwords);
            ^
/home/ubuntu/avmm_dma_linux/altera_dma.c: In function ‘rp_ep_compare’:
/home/ubuntu/avmm_dma_linux/altera_dma.c:313:8: warning: ‘ep_tmp’ may be used uninitialized in this function [-Wmaybe-uninitialized]
        printk(KERN_DEBUG "ep_tmp = %08x\n", ep_tmp);
        ^
scripts/basic/fixdep: 1: scripts/basic/fixdep: Syntax error: "(" unexpected
scripts/Makefile.build:314: recipe for target '/home/ubuntu/avmm_dma_linux/altera_dma.o' failed
make[2]: *** [/home/ubuntu/avmm_dma_linux/altera_dma.o] Error 2
Makefile:1236: recipe for target '_module_/home/ubuntu/avmm_dma_linux' failed
make[1]: *** [_module_/home/ubuntu/avmm_dma_linux] Error 2
make[1]: Leaving directory '/usr/src/linux-headers-3.10.96+'
Makefile:9: recipe for target 'all' failed
make: *** [all] Error 2

Note the error at line 64.

Finally, my Makefile

obj-m	:= altera_dma.o

KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD       := $(shell pwd)

CPPFLAGS += -include $(KERNELDIR)/include/generated/autoconf.h

all:
	$(MAKE) -C $(KERNELDIR) M=$(PWD)

install:
	./altera_dma_load

clean:
	rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions *.symvers *.order

Those changes do look valid, and I’ve used both the NVIDIA-supplied compiler and Linaro. In the case of Linaro yours is version 5.3-2016.02, I used 5.3-2016.02-rc1 (the two should be so close it won’t matter).

Be sure that you’ve used the “/proc/config.gz” from the running Jetson, or “make tegra21_defconfig” for starting config (plus don’t forget CONFIG_LOCALVERSION). See if you can build the whole kernel even if you are only interested in modules. For modules only be sure you run “make modules_depend” before the actual modules.

I assume you have have also set this (or its equivalent):

export TEGRA_KERNEL_OUT=${L4T_OUT}/stage
export TEGRA_MODULES_OUT=${L4T_OUT}/modules

…in which case make sure all commands use the proper option, e.g., “make tegra21_defconfig” would be invalid, you’d need “make O=$TEGRA_KERNEL_OUT tegra21_defconfig” and “make O=$TEGRA_KERNEL_OUT modules”…the module install step would require “make O=$TEGRA_KERNEL_OUT modules_install INSTALL_MOD_PATH=$TEGRA_MODULES_OUT”.

If this error persists then either the edits were not visible or a new error was introduced (in which case knowing exactly where it claims the error is might help to figure it out…some output log prior to this may help):

scripts/basic/fixdep: 1: scripts/basic/fixdep: Syntax error: "(" unexpected.

Thank once again linuxdev. I found the cause of the error I was seeing and am able to advance to stage 2 of the build where the object file (.o) is converted to a kernel object file (.ko). I was missing the make modules_prepare step.

Now I am getting into stage 2 and see the error

Building modules, stage 2.
  MODPOST 1 modules
WARNING: "copy_to_user" [/home/ubuntu/avmm_dma_linux/altera_dma.ko] undefined!
WARNING: "copy_from_user" [/home/ubuntu/avmm_dma_linux/altera_dma.ko] undefined!
WARNING: "kzalloc" [/home/ubuntu/avmm_dma_linux/altera_dma.ko] undefined!
  CC      /home/ubuntu/avmm_dma_linux/altera_dma.mod.o
  LD [M]  /home/ubuntu/avmm_dma_linux/altera_dma.ko
make[1]: Leaving directory '/usr/src/linux-headers-3.10.96+'
insmod: ERROR: could not insert module ./altera_dma.ko: Invalid module format

during stage 2.

Any thoughts?

I think I know what is going on…your commands seem to be trying to install on the PC, not to a temporary directory. The modules are in the architecture of the Jetson (arm64/aarch64/ARMv8), but your PC is x86_64 (thus an error trying to insmod a Jetson module into the host kernel).

In the URL describing procedures you’ll see a number of environment variables and the use of those in conjunction with the compile commands (typically “O=SOMETHING"). If you skip the "O=" you will be using default directories...assuming you use the "O=", but the environment variable was not set, it ends up also using the default install locations. Before building go through each "” variable, e.g., “$TEGRA_KERNEL_OUT”, and verify that the variable is actually set (such as "echo TEGRA_KERNEL_OUT"). If all of those are set and valid, then it should stop trying to install into the host PC and instead install into the temporary directories of the "" substitution.

Thanks linuxdev. I am trying to build and install an external module on the TX1 target. I am not rebuilding the kernel on the target. The target has been flashed with jetPack L4T R24.2.1 built on an Ubuntu 14.04 x86_64 host.

This is the stage which says there is a mixing of architectures, where the wrong architecture is being inserted on the machine which produced the message:

insmod: ERROR: could not insert module ./altera_dma.ko: Invalid module format

So assuming this message occurred on the desktop PC host, it means the environment was not set up correctly and the Jetson module is being inserted on the PC.

If instead this message occurred on the Jetson, then it means the module was built incorrectly on the PC as x86_64 and was not cross compiled to arm64.

Which machine produced that message, PC or Jetson?

The module was built on the TX1 using

obj-m	:= altera_dma.o

KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD       := $(shell pwd)

CPPFLAGS += -include $(KERNELDIR)/include/generated/autoconf.h

all:
	$(MAKE) -C $(KERNELDIR) M=$(PWD)

where KERNELDIR points to the JetPack R24.2.1 build directory on the TX1. The build appears to finish without error. The error occurs when attempting to

/sbin/insmod ./altera_dma.ko

on the TX1. I agree with you that the build on the TX1 may have produced an x86_64 object file. However, I have verified that ARCH=arm64 on the TX1. Plus, the kernel that was produced using the cross compiler on the x86_64 Ubuntu host then flashed on the TX1 boots fine. This proves that ARCH was correctly set to ARM64 when the kernel was built.

It would be quite unusual for an x86_64 cross compile tool chain to be added as a foreign architecture on a Jetson. Something which would be more common is that an ARMv8 system (running arm64/aarch64) would have a tool for armhf…the ARMv7 compatibility mode is supported on the TX1 and TX2.

You can use the “file” command directly on altera_dma.ko to see what the system thinks it is. On a PC here is an example for module nvidia.ko:

nvidia.ko: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), BuildID[sha1]=d0b59845039d0ad5c23826d39b3289d8e639626d, not stripped

Thanks for the tip linuxdev. This confirms that altera_dma.ko is arm64 format

ubuntu@tegra-ubuntu:~/avmm_dma_linux$ file altera_dma.ko
altera_dma.ko: ELF 64-bit LSB relocatable, ARM aarch64, version 1 (SYSV), BuildID[sha1]=f24178a475b9907527de275a941f3acff918ad68, not stripped

The driver message from insmod is

[  792.585890] altera_dma: version magic '3.10.96-tegra SMP preempt mod_unload aarch64' should be '3.10.96+ SMP preempt mod_unload aarch64'

The running kernel is

ubuntu@tegra-ubuntu:~/avmm_dma_linux$ uname -r
3.10.96+

The original kernel flashed from the JetPack L4T distribution was named 3.10.96-tegra. I re-flashed the TX1 with 3.10.96+ from my build of the R24.2.1 sources. I still see the /lib/modules/3.10.96-tegra directory present next to the /lib/modules/3.10.96+ directory, but the running kernel is 3.10.96+.

Any thoughts on what is going on here?

[s]The base version of “uname -r” is the kernel source version, e.g., “3.10.96”. The CONFIG_LOCALVERSION sets the suffix, e.g., if it is “-tegra”, then “uname -r” will show “3.10.96-tegra”. Modules are always searched for in location “/lib/modules/$(uname -r)/”

So the first thing to know is that if you change “uname -r”, then you have to make sure all of the modules are built and added new to the new module directory. Some of those are not part of the kernel build, they are from the driver package (the NVIDIA files are basically the “extra” subdirectory of the “/lib/modules/3.10.96-tegra/extra/” location and would need copy to the “/lib/modules/3.10.96+/extra/” location when your uname -r changes in this way). It is not an error to leave the old modules in place since you may have a reason to test boot the original kernel (U-Boot allows multiple boot entries if you use serial console).

Although not using CONFIG_LOCALVERSION correctly could result in not finding modules the case seems to be that your module was built using x86 architecture. This in turn implies the environment variable “ARCH” was not set to arm64 (e.g., if you set this in one console, but build from a different console, then the ARCH environment variable won’t be visible in the different console). You must be absolutely certain that you have done “make mrproper” and “make O=$TEGRA_KERNEL_OUT mrproper”, then start over with “ARCH=arm64”.[/s]

I’m afraid that I lost you here. I confirmed that the module’s kernel object, altera_dma.ko, is in arm64 format using the file command.

ubuntu@tegra-ubuntu:~/avmm_dma_linux$ file altera_dma.ko
altera_dma.ko: ELF 64-bit LSB relocatable, ARM aarch64, version 1 (SYSV), BuildID[sha1]=f24178a475b9907527de275a941f3acff918ad68, not stripped

Sorry, I did miss that, guess I’m getting too tired and haven’t had coffee…too much 64-bit not enough caffeine.

First, verify this is in the right location for “/lib/modules/$(uname -r)/kernel/drivers/wherever/altera_dma.ko”. Second, run “sudo depmod -a”…does this show any error? Then “sudo modprobe altera_dma”. After that, does “sudo modinfo altera_dma” show anything?

You may want to run “dmesg --forever” while doing this and see if log messages say anything.