Build RSDIS_HOST Kernal module on Orin nano (Network error)

Kernalmodule

CONFIG_USB_NET_RNDIS_HOST is not set

in the Orin nano module for jetpack 6.0
What is the best way to enable it, I have tried to build it but there are many changes I have to manually build all the packages. Need help regarding the same.

The usual method, if a package is available as a module, is to start with kernel source that has an exact match to the running kernel configuration. This includes setting CONFIG_LOCALVERSION. Then use a dependency-aware editor (such as menuconfig or nconfig; the latter is my favorite, it has symbol search) to add features as a module. One can simply copy the new module to the correct location for this case.

Not all features can be in the form of a module, and if you run into this case, you’ll start the same way, but alter the CONFIG_LOCALVERSION. This causes module search to go to a new location. For this case the kernel itself and all modules must be installed, which is more involved.

If you do need to install something, beware that the official documentation usually is about adding edits to the flash software, and then flashing, but for many cases a full flash is not needed.

Can you provide the steps for building kernel and then flashing steps for Orin nano. I have tried but changes are not being reflected.

I’m only considering the default kernel from the L4T release without any customized o/s content in this. If you look at the L4T release via “head -n 1 /etc/nv_tegra_release”, what do you see? Use that to find your content here:
https://developer.nvidia.com/linux-tegra

This is where you would download sources. Note that “driver package” is the flash software, but “driver package (BSP) sources” is a package that contains other sources, one of which is the kernel source. If you download this you will get the main source file:
public_sources.tbz2

Within that is:
Linux_for_Tegra/source/kernel_src.tbz2

This can be extracted without extracting all of the other content (it is a lot of disk space). To see the name of all packages/files within this package, but filtered for the word “kernel”, you can do this:
tar --list -jf public_sources.tbz2 | grep -i kernel

To extract just “kernel_src.tbz2”:
tar -xjf public_sources.tbz2 "Linux_for_Tegra/source/kernel_src.tbz2"

To extract everything that starts in “Linux_for_Tegra/source/”:
tar -xjf public_sources.tbz2 "Linux_for_Tegra/source/"
(you won’t need everything there, but you will probably want to extract all of that; only the kernel and its out of tree content will likely be needed, a small subset of that)

To then extract the one kernel source file (the previous extract process creates subdirectory “Linux_for_Tegra/source/”:

cd Linux_for_Tegra/source/
tar -xjf kernel_src.tbz2
# Optionally, depending on circumstances:
tar -xjf kernel_oot_modules_src.tbz2

“OOT” is “Out of Tree” content. This is content which is accessed in the configuration of the regular kernel source, but not actually found in that source. The build uses relative paths to find the OOT content if and only if configuration has specified that content. This is how a third party vendor would ship some of its own code which is not integrated into the stock kernel source. There is a high probability that the default build would require this content. It’s easier to just install that content now rather than waiting for a failed build. The rest of the files don’t really need extracting.

JetPack 6 has changed a few things, so I do advise that for compile you start with the official documentation from that specific release at the URL above. Go to the “Kernel Customization” section of that documentation. This offers information on cross-compiling, and also the correct compiler or other tools to cross compile from an Ubuntu host PC. There may be other sources (such as display driver) that you would be interested in, and I think the official docs will cover that. You are probably interested in unpacking

As far as the general instructions go consider that a kernel is a tightly coupled set of smaller programs running together. The make target of “tegra_defconfig” is the method to get the initial configuration setup. On your host PC this will be one of the steps in the official docs. You will also set CONFIG_LOCALVERSION to “-tegra”. At this point you would be ready to edit with a make target such as menuconfig or nconfig (nconfig is better since it offers symbol search…CONFIG_LOCALVERSION is one example of a symbol). This is an example of a symbol you could search for to navigate to with nconfig:
CONFIG_USB_NET_RNDIS_HOST

If you enable this with the m key, then it selects building this as a module. If you enable this with the y key, then it modifies the base kernel itself. Not all features are available as module, and in a few rare cases, not all features are available to integrate directly into the kernel. You want the m key if this is allowed (the menuconfig or nconfig editor is dependency-aware, and won’t allow an invalid selection).

If you can get to the part in the official docs where you cross compile up to configuring with tegra_defconfig and CONFIG_LOCALVERSION is set (there is more than one way to set this), then you are ready to build. When you get to that point just ask for more information. In the end there will likely be a file with a “.ko” suffix in one of the build output directories, and you’ll copy that to the Jetson. That’s basically it if you install a module which is from source code that was configured to match the existing kernel configuration, and then added to via only module additions.

Do note that NVIDIA has some scripts for source building, but I’ve never used those. Some of that is for unpacking, which I’ve shown you how to do manually.

how to change the the state from ‘n’ to ‘y’ while doing make through nconfig or menuconfig, I am able to search the driver through system search but not able modify that.

If the symbol is selected, then pressing the n key should disable; pressing the m key will enable in module format if this is allowed; pressing the y key should enable in integrated format. Modes which are not allowed would imply a conflict (e.g., not all features have the code to be a module, e.g., something like virtual swap is so invasive it is only available as an integrated feature).

okay, Thanks for that. I was successfully able to change the RNDIS_USB driver to m. But what is happening right I am compiling and building kernel source on the server (Linux_for_Tegra Folder) from where we can able to flash the board through script but somehow when I try to reflash the board its not booting after that. I am updating the Image and dtbs in the folder what else need to do. I also tried to manipulate the config file in the board itself it also doesnt boot then.
I need guidance regarding what all packages needs to changed and updates after the building the config from kernel_out and modules_out folder

Let’s start with your particular hardware. We know this is a Jetson Orin Nano. You have not specified though if the carrier board is from NVIDIA. If the carrier board and module were sold together by NVIDIA (or one of its distributors), then it is a developer’s kit. Sometimes people purchase a third party carrier board, in which case this is not a dev kit. Third party versions usually have eMMC memory, and very likely have different firmware (device tree) requirements due to changed lane routing or features in the carrier board (the module software would be the same for the most part, but carrier boards do not function entirely correct without the right device tree). Is this a dev kit? Is this a third party carrier board?

You will find a lot of documentation about adding a new kernel and modules and device tree for use in flash. Unless you are manufacturing and wanting all flashes to just include your content you should ignore that. Steps for installing a module are quite simple and do not require flash. If you also install the integrated kernel (the Image file) get a lot more complicated, but still do not mandate flashing. Someone who has burned security fuses must use flash to install the kernel since checksums inside of partitions which are signed become mandatory when those fuses are burned.

I suggest you just take a normally running Orin Nano, configure your kernel source on the host PC to match it, then add the RNDIS as a module, and then do nothing more than copy that resulting individual .ko file to the Jetson (e.g., via scp/ssh). If you used the same kernel source as the default running system, and if you’ve configured it to match that (which the tegra_defconfig should almost do for any default system), and if you’ve matched CONFIG_LOCALVERSION (the other part of matching config) to “-tegra”, then there is nothing but a single module file to copy.

This change won’t require any change to Image for this case. This change won’t require any device tree change unless you have a third party carrier board. For this particular case the loadable module is compatible with the existing kernel and it only loads after the o/s has booted. You can additionally add that module to an initrd if the feature is used for booting (there is no need to add anything to the initrd that isn’t part of boot).

it is a dev kit from Nvidia only, I will try your way and get back to you if I face any issues.

I have tried which you suggested I configured the kernel in the host pc
using steps shown in this file NVIDIA Jetson Orin Nano - Kernel Compile (ridgerun.com)
but I was not able to figure out which .ko file needs to be copied in the orin-nano, so I copied the whole module_out while contains data of /usr/lib/modules/5.15.122-tegra/ so i replaced that whole folder by which I built in host pc, then the orin nano is booting but no usbs or wifi are working after that. So may be files are not compatible Can you guide me which specific .ko file should be copied in order to boot orin successfully and access ethernet over USB.

Was USB working before?

As to the particular file, what symbol did you modify? Let’s say you are in the top directory root of the kernel source. If your symbol is CONFIG_USB_NET_RNDIS_HOST, then you can find out locations for this:
grep -R CONFIG_USB_NET_RNDIS_HOST | grep Kconfig

The subdirectory where Kconfig has this symbol will be the location in both the output of the build (the subdirectory, not necessarily the parent since you have a separate output location…the “shape” of the subdirectory will remain constant) and the subdirectory of “/lib/modules/$(uname -r)/kernel/”.

If you edited the config without a dependency-aware editor (e.g., menuconfig or nconfig), then something may have broken from the config. It is possible there were more files in your existing module directory than what your output was, so deleting (versus overwriting) might have removed some drivers. I would not advise normally replacing the whole directory. You might need to reflash to get a better starting point, although you could clone or save some content first. Also, if you still have your original flash content on the host PC, then modules would exist in the “Linux_for_Tegra/rootfs/lib/modules/$(uname -r)/kernel/”, and a recursive copy of the modules there could solve the issue (for example, using ssh over wired ethernet since USB does not work).

yes I have tried this way but still giving resulting in failed boot where USB wifi ethernet are not working. I am configuring file using menuconfig where I am changing multiple device drivers and module as yes ‘*’ for running RNDIS host successfully. I have a big question why all the common kernel drivers and modules like RNDIS, ethernet over usb, and other kernel depends on usb are disabled in the jetpack 6 image which were enabled in till Jetpack 5.0.2. I am trying to upgrade to Jetpack 6 but unable to successfully achieve that. Trying to configure and build the kernel from scratch again but unable to do that as I have no prior experience in kernel side. I might be making mistakes in building as driver or just as modelizer feature in config as I am not clear about that too. If you can, please provide me on image file which has RNDIS and ethernet over USB enabled.

Answering “yes” (the *) greatly complicates things and makes installation more difficult. Is there a reason for doing it this way? Some drivers don’t allow m (module) format, but installation changes a lot this way. This will cause old drivers to fail to load in many cases.

I don’t know why those specific drivers don’t exist in the current build. Not everyone uses those, so it would waste storage space and CPU cycles. Installing a driver (at least as a module) is more or less trivial, but if it becomes sufficiently useful, probably NVDIA could add that back in.

The kernel release in JetPack 5 (L4T R35.x) is far different than the kernel source of JetPack 6 (L4T R36.x). There isn’t a direct copy of config from one to the other, so I imagine someone manually went through the build options and perhaps spent months adjusting for that change. It might have just been a missed symbol/driver that would have made its way in if there were more time (I don’t know).

Can you build as a module instead of integrated?

okay I will try to build that as module and revert back to you

I have tried building as M (modulize feature), the change has been reflected in the .config file and built successfully. I have tried 3 ways but none of them worked successfully.

  1. Replaced the updated kernel-source in the path of /usr/src/linux-headers-5.15.122-tegra-ubuntu22.04_aarch64/3rdparty/canonical/linux-jammy/kernel-source/ and replaced modules in the path of /usr/lib/modules/5.15.122-tegra/ but in this case USB and WIFI stops working after rebooting the system.
  2. Tried to replace only driver folder of Kernel-source and module (5.15.22-tegra) because RNDIS_HOST file is changed in those locations but it didn’t reflect any changes, issue still persists.
  3. Tried to only copy the 5.15.22-tegra/kernel/drivers/net/usb/rndis_host.ko
    file to existing pkg that did not work too may be some dependencies still pending.

Also when I am trying to build the kernel source while doing make -C tegra_defconfig, it is observed that in the public_sources.tbz for 36 (jetpack6 version) there is no config named tegra_defconfig in arm64 pkg. There are two configs: defconfig & tegra_prod_defconfig. While trying to builld through that it gives modules as 5.15.22-tegra & 5.15.22-prod-tegra respectively. Which one I should follow in order to get compatible to existing orin-nano.

@linuxdev Shouldn’t NVIDIA BSP team handle issue and include the common driver in JP 6.0 ? Why there is huge effort require to enable it ?

If we were in the Windows world, then every manufacturer would build their own modules, and Microsoft would distribute it (at least for automatic install; manufacturers usually supply the drivers separately too). This isn’t really an “NVIDIA thing”, it is all of Linux. Other people (from multiple organizations) build and maintain individual drivers for desktop PC architecture. Anything which is common probably should be included on a desktop, but embedded systems have limited space…all drivers could be installed, but there would be no space left! Building software is a common practice in the Linux world, which is why some people don’t like it, but also is why it works so incredibly well once learned.

You should use full independent kernel source, not just headers for most cases on a Jetson. Then you configure the whole source as a basic match to the running system with the “tegra_defconfig” build target. After that, you set CONFIG_LOCALVERSION to “-tegra”. This is the starting match to the running system, a prerequisite to making a module load into a given kernel. This is built into the kernel source, and the file kernel_src.tbz2 is what contains the source, but this is a file within another .tbz2 file. I don’t know what your L4T release is, and it would help to know this (use “head -n 1 /etc/nv_tegra_release” to find this). The sources file would be from here using the correct L4T release:
https://developer.nvidia.com/linux-tegra

You must extract kernel_src.tbz2 from that, and then extract that kernel_src.tbz2 file into full source. You get everything there, no outside reference to /usr/src/linux-headers... is consulted, nor is any other reference needed. RNDIS should be a symbol within that source, and so there is no RNDIS to download or install…it is there, you just have to configure it. If you’ve replaced all modules, and if that was not the correct module config, then all modules will then fail. The goal is to only add just the file (with .ko extension) that is the RNDIS driver, and nothing else.

The way you verify existence or failure is from the “/proc/config.gz” file and/or the output of “lsmod”. The config.gz only shows what the kernel config was when compiled, so it might miss updates to module files. The lsmod command shows which modules are loaded, and those only load if the hardware is present and the driver can function. Drivers not loaded (but in module format) won’t show up in lsmod.

Regarding networking in general, Linux has its own issues that are unrelated to Jetsons or NVIDIA. Some networks are unmanaged, and other network devices are managed. Wi-Fi in particular, by default, is managed. That means the presence or absence of other networks can cause Wi-Fi to go up or down. Wi-Fi usually runs only when the end user logs in to the GUI…this is active change to the status of Wi-Fi dependent upon circumstances. Wi-Fi also tends to override wired networking, which is another annoying management detail. NVDIA does not design this, nor have anything to do with how Ubuntu works with that. Those issues can in fact be circumvented at times by removing management and making the services static and thus unmanaged. I usually hate dealing with stopping managed services from doing things I don’t like.

If USB actually stops working though, then that is an issue. If you are losing a USB network device, then this is not necessarily USB failing. USB is just a data pipe with some intelligence. I don’t know enough about RNDIS though to be of use in finding out about why its configuration is doing something you don’t want. All I can help with is getting the RNDIS kernel driver in place so that success is possible.

Incidentally, going back to drivers, one only adds a kernel feature with a dependency-aware tool. The menuconfig and nconfig build targets are examples…those editors understand dependencies, and if RNDIS has other subdependencies, then it will enable though. If there are no other dependencies, then copying the one file and running sudo depmod -a would be all that is needed. If there are other dependencies, and if more modules were built, then you must copy all of those .ko files to their correct location before running sudo depmod -a.

Observe the exact uname -r of your running system. You are mentioning multiple suffixes of “-tegra” (normal) and “-prod-tegra”. The base kernel, the integrated file, is entirely different if you are getting two answers. You have two kernels. The modules built against one won’t load into the other. Your -tegra modules need to go in the correct -tegra module directory, while the -prod-tegra has to go in the different kernel’s module directory. They most likely will fail if you mix them. If your running system says -tegra, then those are the modules you should load that were compiled with CONFIG_LOCALVERSION of “-tegra”. If the running system says “-prod-tegra”, then you use the modules compiled with CONFIG_LOCALVERSION of “-prod-tegra”. Just beware that having the CONFIG_LOCALVERSION match is not enough by itself…you still have to have the basic initial configuration used to compile modules match that of the kernel Image (the Image is what answers the “uname -r” command…it’s telling you where it is searching for modules).

If you are missing the tegra_defconfig target, then I think you are using the wrong source, or the wrong directory within the source.

If you have replaced the base kernel, and not just modules, then you might be getting a mix of content that is breaking your efforts. This is ok if you are picking different kernels during boot. I prefer to leave the old kernel in place if I am building an entire kernel, and adding an alternate boot entry for safety. There is no need to worry about that complication if you are only adding a module.

Okay, I understand the problem might not be from Nvidia side, Let’s debug step by step the we both will have more clarity:
First on the host pc I downloaded public_ sources.tbz from given link for the Jetpack 6.0 L4T 36.2: https://developer.nvidia.com/downloads/embedded/l4t/r36_release_v2.0/sources/public_sources.tbz2
Extracted the bsp source and then extracted kernel_src.tbz…
which results into this folder structure.

I followed the steps from given site: NVIDIA Jetson Orin Nano - Kernel Compile (ridgerun.com)

When Trying to make -C xxxxx tegra_defconfig, in the given folder structure ti gives there is no tegra_defconfig in the path of arch/arm64/configs which is shown here so my question is which file should be used defconfig or tegra_prod_config

uname -r of Orin nano is
image

  • Also I tried coping only rndis_host.ko but it didn’t reflect after booting in /proc/config.gz.

What directory do you name in the “-C ...somewhere...”? Depending on kernel source, it is possible that you are using the wrong directory. What do you see with ls if you cd into the kernel/ subdirectory?

I have used given command
make -C kernel/kernel-jammy-src/ ARCH=arm64 O=$KERNEL_OUT LOCALVERSION=-tegra CROSS_COMPILE=${CROSS_COMPILE_AARCH64} tegra_defconfig