Broken symlink in /lib/modules/*/build


I’m trying to build a kernel module, but I’m having an issue where /lib/modules/$(uname -r)/build is a broken symlink pointed at /disk2/parker/linux4tegra/branches/28.1_cam/tegra_kernel_out, which obviously does not exist on my machine.

Does anyone know where this path came from or how to get the full headers correctly installed?

uname -r returns 4.4.38+, and this is a TX2.


“build” and “source” are created at the time “make modules_install” is run. These point at configured headers and kernel source where the build actually took place. On a desktop PC you won’t find full source unless you’ve installed the right dev packages. Basically those links are a reflection of the machine the source was compiled on and are not actually needed unless some sort of packaging is building its own modules against that tree.

The “uname -r” you have indicates kernel source is version 4.4.38. The “+” is appended when built from the source. If you had set CONFIG_LOCALVERSION, then this would have been in the middle (and it is highly advisable to add a custom CONFIG_LOCALVERSION to each build). Example if CONFIG_LOCALVERSION had been “-test”:


You’ll need modules located at “/lib/modules/4.4.38+/” ("/lib/modules/$(uname -r)/") for that particular kernel.

If you were to build the kernel and modules natively on your Jetson, and run “make modules_install”, then this would put the symbolic links in such that they would point to your source. I tend to ignore these because my source can be wiped out and rebuilt at any time…I’d rather not have the links since I have no automatic module building packaging system and because for such source to be valid after many kernel compiles you’d need to have a different directory for every version (and every version means every configuration and not just source code differences).

On a desktop PC with all kinds of automated package updates (where I configured to keep the last 5 kernels) there are a lot of saved kernel headers/sources. I don’t mind this on the PC…it would consume the Jetson’s disk space though.

Hi Linuxdev,

Thanks for that, that was very informative. So it sounds like what I need to do is find the kernel source which corresponds to 4.4.38, build it, and then make modules_install. Is that correct?

This is correct. Keep in mind though that if you read docs on kernel builds you’ll see an option to set an alternative build and output directory…this is recommended versus having modules or kernel install directly to their end destinations (and in fact I doubt direct install of the main kernel Image would even work since the boot logic differs for Jetsons versus other platforms). Just build as normal and then install to alternate location…followed by copy of specific files you are interested in.

When you see references in kernel build documentation of “O=/some/where” (or setting environment variable “TEGRA_KERNEL_OUT” and then “O=$TEGRA_KERNEL_OUT”) you are specifying a clean output location. Similar for “TEGRA_MODULES_OUT” being set to an alternate directory and seeing “INSTALL_MOD_PATH=$TEGRA_MODULES_OUT”.

Typical commands if you’ve set those environment variables and have placed your desired “.config” in “$TEGRA_KERNEL_OUT” (likely a copy of “/proc/config.gz” which is decompressed and has had “CONFIG_LOCALVERSION” edited) and are compiling natively on the Jetson:

sudo nvpmodel -m 0
sudo ~ubuntu/
make -j6 O=$TEGRA_KERNEL_OUT Image
make -j6 O=$TEGRA_KERNEL_OUT modules

Note that after this you could cd to $TEGRA_KERNEL_OUT and “find . -name Image” to get the kernel image. An entire tree of modules will be found under a subdirectory of “$TEGRA_MODULES_OUT”. Then you can pick what you want to copy.

NOTE: Be careful if you copy all modules recursively…you want to remove those sym links first because otherwise it’ll copy your entire kernel source tree…you can add sym links back in later if you want.