How to activate linux device drivers on jetson nano?

hello guys ,
I’m trying to use max30102 with jetson nano .
I figure out that this sensor has a device driver on linux kernel.
so do I have to install linux kernel and activated it ?
or is there any command line that could activated it?
also where to add the overlay ?
I was working on raspberry but I like jetson nano and I want to learn more.
any advice ?
thanks .

The default release may not include this driver.
You may need to consult with vendor to get the driver and dts setting to enable it.

Just some notes in addition to what @ShaneCCC mentions: “Often” it is possible to add kernel module just by means of a file copy rather than installing an entire Linux kernel. Don’t do work with flashing that you don’t need. Often the case is that even the kernel can be installed via file copy rather than flashing. In some cases with secure boot or burned fuses one needs to add that content to partitions via a flash, but in most cases flash is not needed and you just need to add a new boot entry to point at the new files in “/boot/extlinux/extlinux.conf”. Just ask if you find the right driver and need to know the easiest way to install.

FYI, in the above I said “often”. The reason is that not all kernel features can be built as a module, although most can. Invasive features (such as virtual memory swap support) tend to not support building as a module. Modules are the kernel, but they are able to load and unload while the system runs. If the modules are compiled against the currently running kernel’s configuration, then there is no need to add the whole kernel…in that case you can just copy a file in place.

hello sir,
thanks or your reply .
Well , On raspberry (raspbian) I had to install rpi kernel linux then activated device driver → <> industrial i/o → <> MAX30102.
then I add the overlay got it from linux kernel documentation and add i2c because it uses i2c bus into arch/arm/boot/dts/overlays as max30120-overlay.dts then compile in into max30102.dtbo
add max30102.dtbo to arch/arm/boot/dts/overlays/Makefile
copy max30102.dtbo to /boot/dts/overlays
add dtoverlay = max30102,i2c
is it the same steps ?
if yes , where to add the overlay?

thanks sir for you reply,
but I really don’t know how to do it ?
will you please tell me more?

Do you mean how to build a kernel module or kernel? The official docs mention how to do this from the host PC (it uses cross compiling), but the install would differ (you wouldn’t use flash). Official docs are listed with your release, and a list of releases are here:
https://developer.nvidia.com/embedded/jetpack-archive
.then look for the kernel customization part.

The gist of something which needs to be emphasized is that you will see a reference to compiling “tegra_defconfig”. This configures the kernel to the NVIDIA defaults prior to performing the actual build of a kernel or modules. If this matches, then modules you build should work with your existing kernel, and a simple file copy of the module finishes the job. However, if the configuration does not match, then the module will fail to load. Make sure to configure prior to building.

You will see references to building kernels and modules. Even though you probably don’t need to build the kernel (and this takes time) it is still a good “sanity check” to see if this works prior to attempting to build modules.

The part many people miss is specifying where kernel modules are located. Before you build your kernel or “make tegra_defconfig”, check what the running system shows for the command “uname -r”. The command will report something like “4.9.140-tegra”. The “4.9.140” part is taken from the kernel version, but the suffix is something you must specify. In the kernel build there will be a “.config” configuration file, and for that example, you would edit that line to be:
CONFIG_LOCALVERSION="-tegra"
…which sets the suffix and would imply a matching “uname -r”, which in turn would mean the kernel will be able to find modules here:
/lib/modules/$(uname -r)/kernel/...some subdirectory.../some-kernel-module.ko

Just to reemphasize, kernel docs mention install steps which usually imply flashing. Ignore those steps, don’t do them. If you built something like a filesystem type driver, then you’ll have a “.ko” file somewhere in the “fs/” subdirectory of the kernel source, and then you’d simply copy it to the Jetson’s “/lib/modules/$(uname -r)/kernel/fs/something.ko”, and reboot. No flashing.

I just want to active max30102 from linux kernel .
I figured out that this sensor doesn’t have a device driver on linux kernel 4.9 . So I will use max30100.
I tried to follow this doculentation :
https://docs.nvidia.com/jetson/l4t/index.html#page/Tegra%20Linux%20Driver%20Package%20Development%20Guide/hw_setup_jetson_io.html#
I got an error when I tried to compile the overlay:
dts-v1/;
/plugin/;
&i2c1 {
status = “okay”;
#address-cells = <1>;
#size-cells = <0>;
max30102@57 {
compatible = “maxim,max30102”;
reg = <0x57>;
maxim,red-led-current-microamp = <7000>;
maxim,ir-led-current-microamp = <7000>;
interrupt-parent = <&gpio1>;
interrupts = <16 2>;
};
};
$ dtc -O dtb -o my-overlay.dtbo -@ max30100-overlay.dts
Error: max30100-overlay.dts:1.1-2 syntax error
FATAL ERROR: Unable to parse input tree

do you know how to correct it?
thanks .

Note that I don’t know which driver is the one for your device. Perhaps the max30100 driver will work in place of one for the max30102, but I don’t know.

Probably the first thing needed is to know that the kernel source won’t compile correctly unless it is configured correctly. In the case of loadable modules, this also means the configuration has to match the running kernel. A module is part of the kernel, and the ability to load and unload that module requires the rest of the kernel configuration to be compatible.

Before you start, write down what you see from “uname -r”. The result will be something similar to “4.9.140-tegra”. The “4.9.140” is from the kernel source version, and the “-tegra” is from someone setting this up in kernel configuration prior to compile. More on this later on…

Just a head’s up: When I show kernel build targets, e.g., “make tegra_defconfig”, that’s just the basic command. There are other items used for cross compile for example, or setting the temporary content output location somewhere other than in the middle of the reference source code. You’ll still have to add that to any commands depending on your situation.

Also, the integrated base kernel file is the “Image”, usually located at “/boot/Image”. You won’t need to change this in most cases. Modules are part of the kernel, but they tend to be loaded as needed, and are found at:
/lib/modules/$(uname -r)/kernel
…which is mostly what you’ll install when you are just adding a driver.

Firmware (mainly device trees) could be in “/lib/firmware”, but the device tree is usually somewhere in “/boot”. What you’ve called an “overlay” is really a set of arguments which gets passed to the driver as it loads (it isn’t really an overlay so much as it is metadata on finding and initializing the hardware). Device trees, when compiled, are “.dtb” files. You won’t find any “.dtb” files in “/lib/firmware”, and for what you are doing, it is unlikely you will ever touch “/lib/firmware”. An example of when content might be there is with WiFi (with different firmware depending on region of the world…there is legal compliance involved). I suppose a sensor might have firmware other than device tree, but it is very low probability.

When you have your kernel source the first thing you do with it is to set the configuration. None of your compile or build steps are valid without this. Often you’ll get errors related to features missing or being incompatible…unless you’ve set up a valid configuration.

There are two kinds of configuration you might start with. The first is the “default” configuration which NVIDIA provides. This is through the build target “make tegra_defconfig”. In theory every shipped Jetson starts with this, though there is no guarantee it hasn’t been slightly modified over time. If you’ve never changed the base kernel Image, then tegra_defconfig is likely a near exact match to your running kernel configuration.

The second method of configuring is to use the decompressed version of “/proc/config.gz” (and renamed) as a starting config. With the exception of one config item, this is a guaranteed exact match of the configuration of the running kernel. No matter what may have changed over time, this is the superior start point for kernel config if you want to be sure it is a match.

When you “make tegra_defconfig” it will create a config file, “.config” in the correct location. If you copy the “/boot/config.gz” to that same location, gunzip it, and then rename it to “.config”, then this is exactly the same thing. Every menu editor or other config change should start with one of these.

In both config methods I say “almost” exact matches. There is a single config item which won’t match: CONFIG_LOCALVERSION. Remember that suffix from “uname -r”? If uname -r shows “4.9.140-tegra”, then you need to edit to this in the .config file to be a true match via the suffix of “-tegra”:
CONFIG_LOCALVERSION="-tegra"
(there are other ways to edit this, but this is the most direct)

You might now use a menu based config editor to change the “.config” file. Dependencies imply it is usually a bad idea to edit the file directly (I happen to know there are no dependencies on CONFIG_LOCALVERSION). Most of the text mode editors require you to add package “libncurses5-dev”. You can do this before configuring: “sudo apt-get install libncurses5-dev”. Most examples will say that after you have run “make tegra_defconfig” you can run “make menuconfig”…this is an editor of config items. I use “make nconfig” because it has all of the same function, but also has a “symbol search” for finding some obscure feature you want to enable.

If you enable your feature as a module (assuming it can be built as a module, though most features can), then you can “make modules”. A big warning though: Unless you’ve gone through steps to make sure the configuration is visible to the modules, it won’t work like you expect. If you’ve run “make Image”, then this is one way to guarantee those configuration features are visible throughout. Thus I recommend running “make Image” once even if you don’t use the Image. If the Image cannot compile, then your other build steps will either fail or be invalid as well. You could instead run “make modules_prepare” before building modules, and skip building the Image.

The target “make dtbs” is what builds device trees. If you want to build this way. This too will always fail if the config was not set up correctly. This is the method many people use, but it is also possible to take the current system tree, export it, edit that one item, and then recompile it. Then copy the updated tree in place. In the error you had earlier there is a significant chance it was due to a simple lack of configuration. If you can “make Image”, and you still get such an error, then you may have found a true bug.

All of the information you see in the official docs for cross compile are good so far as building goes. The install steps I recommend differ since the docs show adding this via flash, whereas I recommend adding newly build content with some simple file copies. Once you have your module and .dtb device tree file from your build, just ask and instructions for adding these will be relatively simple. Official docs come with each specific JetPack/SDKM/L4T release. FYI, JetPack/SDKM is a front end to the actual flash software, whereas L4T is what gets flashed to the Jetson. Pick your release from this list:
https://developer.nvidia.com/embedded/jetpack-archive

Use the “kernel customization” information on what you need to do for building a module, but check the config information I gave here before you actual compile. Probably substituting the renamed/decompressed /boot/config.gz (plus editing CONFIG_LOCALVERSION) should replace the “make tegra_defconfig”. Edit via something like “make nconfig” to enable your feature as a module. Build from there as in the docs. Ask here for install information so you don’t need to do a full flash to add that content.

If you still have a “make dtbs” failure after “make Image” succeeds we can go from there. Be sure to show about a page or so of build output at and before the build error.

hello sir,
thanks for the reply .
I read it all and I don’t understand how to do it exactly I need some command line because I’m still newbie in both linux kernel and jetson nano .
the steps I did on raspberry pi I asked many people to get those steps .
so will you help me more please and tell me what to do step by step with commande line?
Thanks .

Which release are you using? For example, you can see the flashed L4T release via “head -n 1 /etc/nv_tegra_release”. Or you can name the JetPack/SDKM version used to flash the Jetson. Also, verify if this is the SD card dev kit version, or the eMMC Nano.

JetPack 4.5.1 I installed the latest release .

First, go here:
https://developer.nvidia.com/linux-tegra

Then find the JetPack 4.5.1 URL. You would then go to the L4T 32.5.1 URL since you would use SDK Manager to download what you need and/or documentation (remember that it is L4T which flashes, and the JetPack/SDKM is only a front end to perform flashes and download content).

The final document you want is either the downloadable or web-based “Jetson Linux Developer Guide”. Within this, the “Kernel Customization”:
https://docs.nvidia.com/jetson/l4t/index.html#page/Tegra%20Linux%20Driver%20Package%20Development%20Guide/kernel_custom.html

You would start with the “Obtaining the Kernel Sources”, but I will recommend the “Manually Downloading and Expanding Kernel Sources” over the git version (no particular reason other than that I have not verified if something known as “extraversion” is used on the git version).

Then follow the “Building the NVIDIA Kernel” section. Any reference to “make tegra_defconfig” could be replaced with what I mentioned earlier, using the “/boot/config.gz” of the running system instead. Mention of “export LOCALVERSION=-tegra” is shown, and this is an alternate method of setting the “.config”:
CONFIG_LOCALVERSION="-tegra"

As mentioned above, once you have default configuration, you need to use a config editor to add your changes (not using a config editor risks incorrect dependency checking). See my previous reply about “make nconfig” or “make menuconfig”.

Once config has the original system’s configuration, and then you’ve modified it to have your driver, simply compile as shown in those docs. There are so many details being given that you’ll probably think it is complicated, but once you have the source and tools installed it becomes much simpler.

If you have any questions just ask. Once the build completes, you’d find your kernel module (a “.ko” file named after your device driver). Just don’t use the flash commands in the document as the method to install; find the driver file and come back here to ask. Flashing is the hard way to do it.