R32.1 TX2 how can I build extra module in the tegra device

Hello,
recently,I update my jetson system to R32.1,I have a device driver need to build,but when I usb the old method it’s failed in the . what should I do?
thanks very much.

Where is the kernel source installed (in which directory)? Was source downloaded via source_sync.sh?

Do you have your own module source you want to build, or are you trying to build a module from the full kernel source? Do you have a starting config set up already?

Hi,linuxdev
I can build the module from the full kernel source.But for debugging this is very inconvenient, I want to compile on the tegra device, the old method in R28.2.1 is not working, how can it be solved?

I’m not positive of what you mean “when I usb”. More details are needed, e.g., if you are saying USB devices don’t work.

Is the module intended to work with the kernel you currently run (“uname -r” to see version)? I ask because some modules may be intended to work with an older 2.x version kernel, or else depend on a kernel which is newer than the current kernel. If that is the case, then config won’t be available as needed.

If you have not configured, then I wouldn’t expect it to work. Whenever you run a particular kernel you can find its version, along with the “CONFIG_LOCALVERSION”, via “uname -r”. If you cd to “/lib/modules/$(uname -r)/” there should be a symbolic link named “build”. If you then look at where this is, e.g., via this:

ls -l /lib/modules/$(uname -r)/build

…then you will get an answer pointing to which header directory is being used with that particular kernel. If for example this says “/usr/src/linux-headers-4.4.38-tegra/”, then cd there (this is from R28.2 so your kernel version will differ slightly):

cd /usr/src/linux-headers-4.4.38-tegra/

Now copy “/proc/config.gz” there for matching the current configuration:

sudo -s
cp /proc/config.gz .
gunzip config.gz
mv config .config
# Now edit the file and update CONFIG_LOCALVERSION="" to match the suffix
# of "uname -r"...probably it is "-tegra":
CONFIG_LOCALVERSION="-tegra"
# Save and exit the .config file

From here you should now be able to “make modules_prepare”. Without a valid config I wouldn’t expect it to work, and I don’t know if this is the case for your situation, but odds are that it is. If not, then can you give steps you used up until the error, and a log of the error? For example, which config have you added to the headers prior to “make modules_prepare”?

Hi linuxdev,thank you very much!
The “when I usb” is my input error,should be ‘used’.my module driver source can build on R28.2.in the directory /lib/modules/‘uname -r’/build execute the following command :$ sudo make modules_prepare to prepare the kernel source tree for building out-of-tree kernel modules.

For R32.1,I following your prompts,in the directory /usr/src/linux-headers-4.9.140-tegra-ubuntu18.04_aarch64/kernel-4.9/

sudo -s
cp /proc/config.gz .
gunzip config.gz
mv config .config
sudo vi .config
CONFIG_LOCALVERSION="-tegra"
sudo make modules_prepare

Print the information as follows:

scripts/kconfig/conf  --silentoldconfig Kconfig
drivers/net/ethernet/nvidia/Kconfig:30: can't open file "drivers/net/ethernet/nvidia/eqos/Kconfig"
scripts/kconfig/Makefile:37: recipe for target 'silentoldconfig' failed
make[2]: *** [silentoldconfig] Error 1
Makefile:565: recipe for target 'silentoldconfig' failed
make[1]: *** [silentoldconfig] Error 2
make: *** No rule to make target 'include/config/auto.conf', needed by 'include/config/kernel.release'.  Stop.

I want to confirm, was the “Print the information” from the “sudo make modules_prepare” step, or was this from a separate later step in the module source you were building? I’m still looking at an older release, but working on flashing R32.1 to a TX2 now, so I can’t actually attempt to replicate this until done (it’ll be a few hours before I can attempt to run the “sudo make modules_prepare” from an R32.1 TX2). I also want to verify if “uname -r” is “4.9.140-tegra”…is this correct?

Basically what the error is saying is that a config item (in “/proc/config.gz”) was found for a header directory which doesn’t exist. The configuration wants “drivers/net/ethernet/nvidia/eqos/Kconfig”, but it isn’t there (in fact the “nvidia/” subdirectory has no source at all…only the Kconfig and Makefile exist…perhaps NVIDIA left this out or something changed). I am currently in the process of flashing R32.1 to a TX2 (which is going to take me a couple of hours to get through since I do some extra work for logging and setup) and so I can’t see what the “/proc/config.gz” is yet. However, I know in previous releases this directory did exist (the “drivers/net/ethernet/nvidia/eqos/Kconfig” can be found in earlier releases within the header directory), but the sample rootfs of R32.1 does not contain this. The implication is that the running kernel has configured for something not available in the separate kernel headers of the R32.1 headers (the eqos driver).

So the following questions need to be answered next:

  • Is the currently running kernel the default kernel and not modified (the kernel producing the "/proc/config.gz")?
  • If and only if a default unmodified config.gz produced this error, then what do you see from the following:
    gunzip < /proc/config.gz | egrep '(NET_VENDOR_NVIDIA|FORCEDETH)'
    

Those latter two symbols are the ones which the Kconfig would use to invoke features which were left out in the kernel headers. Should those features exist in the running kernel, then we need to find out where the missing headers are at. If these are instead from your new module, then we need to find out which kernel release that module source was designed to work with. Since this content was there previously, and since it is likely the unmodified kernel produced that configuration, I am inclined to believe the headers are missing content (not a guarantee, but this seems likely).

I am sure the information is from “sudo make modules_prepare”. and “uname -r” is “4.9.140-tegra” is correct.

The currently running kernel is the default kernel .

Try just to skip make modules_prepare step and go ahead with building the kernel module. It worked for me. Otherwise you can try doing something like this: https://devtalk.nvidia.com/default/topic/1042391/jetson-agx-xavier/is-it-possible-to-build-kernel-module-in-xavier-solved-/post/5288000/#5288000

It’s not the first time Nvidia breaks kernel headers in new L4T release, it would be nice if they paid more attention to them in the future.

I now have an R32.1 stock TX2 install. I can confirm that the default installed config.gz shows:

CONFIG_NET_VENDOR_NVIDIA=y
CONFIG_FORCEDETH=y

It looks like this code has moved out of tree and is now referenced through relative paths. You could possibly disable those features, but I don’t know what might depend on this. I’d be tempted to agree with @parafin and see what happens if you build your module without the modules_prepare step in the headers directory. However, probably the proper thing to do would be to install the full kernel source in place of those headers (you wouldn’t be building the full tree, but you would use it for header config…removing a couple of integrated features implies you need to change the CONFIG_LOCALVERSION and install the full kernel Image and its modules…having full kernel source and not altering integrated features implies the ability to keep the old kernel and modules…ignoring the modules_prepare might not hurt anything for that particular module, but you might figure out after a lot of work that it did matter).

If you are interested in this, then look at the flash software, find “Linux_for_Tegra/source_sync.sh”. Copy “source_sync.sh” to your Jetson’s “/usr/src/”. Run this from that location:

sudo ./source_sync.sh -k tegra-l4t-r32.1

That script will have created “/usr/src/sources/kernel/kernel-4.9/”. This is the TOP of the kernel source, and the other subdirectories created will have added the out of tree content such that the relative paths can find the headers and source. This particular tree is owned by root, and other than configuring it to match the running system's config, this tree should not be altered. Once this is in place you can go to "/lib/modules/(uname -r)/" and notice the symbolic link “build”. Notice:

ls -l /lib/modules/$(uname -r)/build

…this points at:

build -> /usr/src/linux-headers-4.9.140-tegra-ubuntu18.04_aarch64/kernel-4.9/

…you will want to change the symbolic link to instead point at:

/usr/src/sources/kernel/kernel-4.9/

So do this:

sudo -s
cd /usr/lib/$(uname -r)/
rm build
ln -s /usr/src/sources/kernel/kernel-4.9/ build
exit

Now you can copy the running system’s “/proc/config.gz” to “/usr/src/sources/kernel/kernel-4.9/” instead of the original location, but the instructions are the same from there. Use gunzip, rename as “.config”, change CONFIG_LOCALVERSION to ="-tegra", and run “make modules_prepare” from that new alternate module location:

cd /usr/src/sources/kernel/kernel-4.9/
sudo -s
cp /proc/config.gz .
gunzip config.gz
mv config.gz .config
# Edit and make sure you have CONFIG_LOCALVERSION="-tegra"
make modules_prepare
exit

Now your “/lib/modules/$(uname -r)/build” points there, and when you do an out of tree module build it will reference that tree with the existing system configuration and should work if the new module itself is compatible with that configuration.