TX2i WiFi support

Hello, I am trying to install WiFi dongle drivers for the D-link nano adaptor with Realtek 8188cus chipset.
I followed the instructions I found for the TK1 [url]https://elinux.org/Jetson/Network_Adapters[/url] without luck.
It seems that I have to rebuild the kernel, but I don’t have experience on how to do that. Also I am using the orbity carrier board and if I will rebuild the kernel, I don’t know how to include the drivers of the carrier board.
Can please someone advice me how can I proceed or confirm which WiFi adapter works with TX2i?

Most of what you find on other Linux documentation for kernel build is still valid on a Jetson, but if you cross-compile then extra information is needed. Actual install differs from a PC due to using a different boot mechanism (PCs use GRUB, Jetsons use U-Boot).

The official compile information is available with the Documentation download of your version of L4T. For example, look here (documentation will change for some details depending on L4T version…so get Documentation for your version):
https://developer.nvidia.com/embedded/linux-tegra

Historic version listings:
https://developer.nvidia.com/embedded/linux-tegra-archive

A useful part of the official documentation is information on cross-compile tools. This information is not needed for native compile on the Jetson itself.

Preparation:

Consider using the driver package’s “source_sync.sh” script to get the correct kernel source. If you’ve flashed the most recent JetPack3.3 (a front end to command line tools, plus package management), then your L4T version will be R28.2.1 (see “head -n 1 /etc/nv_tegra_release”). With R28.2.1 as an example, using source_sync.sh from the driver package (which JetPack would have downloaded for you if you used that to flash…it produces the “Linux_for_Tegra/” subdirectory on your host), this would download kernel source (and some related subdirectories for firmware and device tree):

./source_sync.sh -k tegra-l4t-r28.2.1

(you can use this script anywhere…you can copy it to a temporary location on the Jetson itself if you want to compile the kernel natively on the Jetson…other documentation will suggest cross-compile from an Ubuntu PC host…native compile is simpler, but not everyone wants to use the disk space on the Jetson for building)

I can’t help with what changes other carrier boards might require, but if you have a running system now which you’ve flashed to a version you want, then save a copy of “/proc/config.gz” somewhere safe and use a copy of that for any starting config. Also take note of the current output of “uname -r”. On R28.2.1 with a TX2 it is “4.4.38-tegra” (likely the 4.4.38 will be the same on your carrier board, but the “-tegra” probably differs). Note that when someone mentions setting up kernel config via “make something_defconfig” that this is to produce a basic verison of this config file named “.config” in the kernel build area; however, a copy of what is actually running is probably superior. If you have copied a version of config.gz via gunzip and rename to “.config”, then don’t run any of the “make something_defconfig” commands (for a TX2 it is “make t186_defconfig”…I don’t know if TX2i differs…Orbitty probably needs edits to defconfig, but “/proc/config.gz” does not need edits).

FYI, I don’t have a TX2i (and I only have the dev carrier board), so I’m going by the TX2 dev kit for information (for the most part nothing will differ between TX2/TX2i or dev board/Orbitty board which the “/proc/config.gz” sample doesn’t already take into account…device tree is a different story, but you don’t need to know anything about that for a simple kernel build (device tree is a separate topic, but it ships with the kernel source because they are related).

The “/proc/config.gz” file is a gzip compressed copy of the running system’s idea of what the kernel config is right at that moment (it isn’t a real file, this exists only in RAM). With the exception of CONFIG_LOCALVERSION this is an exact match to what you have now. Always copy this somewhere safe before working on a kernel…once you’ve changed your kernel this is lost. You will see kernel compile steps about building a “defconfig” (e.g., “make t186_defconfig”), but the actual starting config is a far better starting point. If your carrier board had to change something, then the “/proc” version of config will reflect that…you won’t even have to know what that difference is (so far as kernel config goes…there may still be other details changing).

When a kernel searches for modules (perhaps you will build your driver as a module instead of integrated into the kernel) it searches at “/lib/modules/$(uname -r)/”. CONFIG_LOCALVERSION is made up of the kernel source base version number (“4.4.38” in most recent Jetsons) plus CONFIG_LOCALVERSION. If you were to set CONFIG_LOCALVERSION to “-tegra” on a “4.4.38” kernel source before building the kernel, then running that kernel would result in “uname -r” of “4.4.38-tegra”, and modules would be searched for in “/lib/modules/4.4.38-tegra/”. Should your modules be located in another directory, then there will be a failure to find those modules (and perhaps this would imply system failure or just some missing feature). Note that you can directly use an editor on the “.config” for CONFIG_LOCALVERSION, or the menu-based editors can do this.

Before you start building you might want to install a package used for some of the command line config editors (this is used for some utilities which work in console even when there is no GUI):

sudo apt-get install libncurses5-dev

Once have your kernel source and get an exact match to your existing kernel config (with file name “.config”) you’ll be ready to edit the configuration for any change you want to make. The “make menuconfig” or “make xconfig” or “make nconfig” arguments in the kernel build location will run an editor (I use “make nconfig”…xconfig is GUI only, but nconfig is what I recommend even if you have a GUI…nconfig has the best “search” function). If you have copied your “/proc/config.gz” to the kernel source parent directory, unzipped it with “gunzip”, and edited CONFIG_LOCALVERSION, then the correct starting config will be automatically loaded when you start that edit. Basically:

cp /proc/config.gz /where/ever/it/is/kernel
cd /where/ever/it/is/kernel
gunzip config.gz
mv config .config
# Note "uname -r", edit .config for correct CONFIG_LOCALVERSION

Build Notes:

You’ll find it useful to know that the basic order is to configure, followed by “make Image” (we don’t bother with zImage or uImage…these wouldn’t hurt, but are not used on a TX2…you’d still get an Image file) to build a kernel, then “make modules” to build any modules. If you were to skip “make Image”, then you’d need to run “make modules_prepare” prior to building modules (building Image does the equivalent of “make modules_prepare”). I suggest always building your config at least once as “make Image” even if you don’t need the Image…it is a sanity check.

Environment variables change how the build is done. The environment which is most useful (regardless of cross-compile or native compile) is to put your work in a directory other than the kernel source itself. Keeping the kernel source clean is an excellent choice. So this contrasts building a kernel and modules in a bad way (polluting the kernel source itself…it isn’t really bad because you can “make mrproper” to get rid of old files, but it is ugly compared to not putting intermediate files there in the first place):

# All methods (for the sake of convenience):
export SRC=/where/ever/your/kernel/source/is/
# Ugly
cd $SRC
# ...configure...results in ".config" being here.
make Image
make modules
# ...Image and modules will be somewhere in the current tree...
# Nice
cd $SRC
mkdir /some/other/empty/temp/location/build
export TEGRA_KERNEL_OUT=/some/other/empty/temp/location/build
mkdir /some/other/empty/temp/location/modules
export TEGRA_MODULES_OUT=/some/other/empty/temp/location/modules
# ...configure...put your ".config" in TEGRA_KERNEL_OUT...
make -j4 O=$TEGRA_KERNEL_OUT Image
# ...Image will be somewhere in $TEGRA_KERNEL_OUT
make -j4 O=$TEGRA_KERNEL_OUT modules
make O=$TEGRA_KERNEL_OUT modules_install INSTALL_MOD_PATH=$TEGRA_MODULES_OUT
# ...modules will be in $TEGRA_MODULES_OUT

If you were to cross-compile from the PC the above would still be true, but you would have to additionally tell the compiler this is for cross-compile:

# This assumes you have cross-compiler "/where/ever/your/cross/tool/is/bin/aarch64-unknown-linux-gnu-<b>gcc</b>
export CROSS_COMPILE=/where/ever/your/cross/tool/is/bin/aarch64-unknown-linux-gnu-
export ARCH=arm64

The CROSS_COMPILE plus ARCH would be done prior to any “make” for a cross-compile. The “.config” would go directly in SRC if doing it the ugly way, or in TEGRA_KERNEL_OUT for the clean way.

Tips:

  • If you run "make mrproper", then you will make the kernel source completely pristine. You will remove any ".config". If you run "make O=$TEGRA_KERNEL_OUT mrproper", then you will completely clean your alternate "nice" way of doing it directory...but there is a catch on Jetsons. There are some other directories related to device tree and firmware which "mrproper" won't clean out for "make O=$TEGRA_KERNEL_OUT mrproper"...you might need to "rm -Rf $TEGRA_KERNEL_OUT/*". If you did everything as a non-root user you will be far safer than if you do this as root...be very careful about recursive rm. Check what an environment variable is with "echo" prior to using it (e.g., "echo $TEGRA_KERNEL_OUT" or "echo $TEGRA_MODULES_OUT").
  • Never use "make modules_install" except with an alternate location specified via the "INSTALL_MOD_PATH=$TEGRA_MODULES_OUT" unless you are absolutely certain you want the results to go into the running machine.
  • Modules, after modules_install, will be in a directory tree matching the subdirectory of the kernel source which you just built. The "/lib/modules/$(uname -r)/" directory will follow this same pattern and can more or less be recursively copied into the correct "/lib/modules/$(uname -r)/" location.
  • The original "$TEGRA_MODULES_OUT" location will contain a symbolic link ("build"). You don't want to copy the content the link point to; it copies the entire kernel build source. This won't hurt, but it sure will eat up disk space. You can safely "rm" the link before a recursive copy.
  • See: "find $TEGRA_MODULES_OUT -type l" to locate the sym link.
  • The Documentation downloadable from one of the above URLs gives information on using environment variables for cross-compile, along with information about cross-compile tools.

About Installing:

If you build a feature as integrated (you used ‘y’ in the menu editor to enable the feature), then the change will be in the Image file of “$TEGRA_KERNEL_OUT”. Install will consist of copying Image to the right location/name of “/boot” (preferably with a name change to preserve the original Image). This may have some things to watch out for.

If you build a feature as a module (you used ‘m’ in the menu editor to enable the feature), then install will go to the right location of “/lib/modules/$(uname -r)/”. Reboot or “sudo depmod -a” will inform the system to look for changes to modules.

If you build a module, then it will be in a subdirectory of “$TEGRA_MODULES_OUT”. When installed it will go in a matching directory tree of “/lib/modules/$(uname -r)/kernel/”. For example, if the module is at “$TEGRA_MODULES_OUT/drivers/foo/bar.ko”, then you’d copy the “bar.ko” file to “/lib/modules/$(uname -r)/kernel/drivers/foo/bar.ko”. You’d need to verify after reboot that your “uname -r” is what you expected.

Sometimes you will see an added “+” in your “uname -r” which you didn’t expect. You might want to recursively copy your previous modules to this location, and then install the new modules over the top of this. Example assuming you had “/lib/modules/4.4.38-tegra/”, and now you have “uname -r” of “4.4.38-tegra+”:

sudo -s
cd /lib/modules
cp -R 4.4.38-tegra 4.4.38-tegra+
cd 4.4.38-tegra<b>+</b>
# You have previously removed the symbolic link in $TEGRA_MODULES_OUT
cp -R $TEGRA_MODULES_OUT .
# depmod -a OR reboot

If you build a feature purely as a module with no other changes (other than adding modules), then the original Image will be guaranteed as compatible with your module. If you change a feature integrated into the Image file, then you are no longer guaranteed that the module is compatible. In many cases you will have good reason to believe there is not a compatibility issue, and thus recursively copying the old modules into the directory with a new “uname -r” will work. For cases where something significant changed in the Image, then you want to purposely use a different CONFIG_LOCALVERSION to get a completely new and separate “uname -r”…in which case you would use only newly compiled modules and not recursively copy anything from the old module directory.

U-boot looks for the Image file via the “/boot/extlinux/extlinux.conf” config. The typical extlinux.conf has an entry like this, and the “LINUX” key/value pair is the location of Image:

LABEL primary
      MENU LABEL primary kernel
      LINUX /boot/Image
      APPEND ${cbootargs} root=/dev/mmcblk0p1 rw rootwait rootfstype=ext4

If you want to add a separate entry while preserving the original you might add this (FYI “LABEL” is what U-Boot looks for, “MENU LABEL” is what a boot menu will show the user during boot):

LABEL <b>custom</b>
      MENU LABEL <b>custom kernel</b>
      LINUX /boot/Image-4.4.38_custom
      APPEND ${cbootargs} root=/dev/mmcblk0p1 rw rootwait rootfstype=ext4

…if your new Image file were then copied to name “/boot/Image-4.4.38_custom” (CONFIG_LOCALVERSION would be “_custom”), then this second entry would boot to that entry and leave the original available for rescue or comparison. You need a serial console to pick this at boot time (there is a short moment during early boot you can hit a key stroke and interrupt U-Boot to pick an entry). See:
http://www.jetsonhacks.com/2017/03/24/serial-console-nvidia-jetson-tx2/

If you don’t have a serial console, then you would probably still be advised to use an alternate entry…but you’d have to set the “DEFAULT” key/value pair at the top of extlinux.conf to name the new “LABEL” (in this example it is “custom”). In the above “DEFAULT custom” would boot the custom entry if nobody manually selects something different at boot. Should this fail, then you’d probably need a serial console to get back in (unless you are willing to spend a lot of time cloning and restoring).

About Your Particular Edits to .config:

Sorry, I don’t know anything about the particular hardware drivers you are wanting to add. If you use a text editor to look at “.config”, then you’ll see a lot of “CONFIG_…something…” lines. Some are integrated already (“=y”), some are inactive and commented out, others are as a module (“=m”). In “make nconfig” you’ll see at the bottom a hot key is available for searching. You can search for symbols, but do not need to use “CONFIG_” in the search (it’ll look for the part after “CONFIG_”). The search also is case insensitive so you don’t have to use capital letters. You will have to research what drivers your hardware uses, find this in the “make nconfig”, and enable it. Usually a driver works for a chipset series and may not be specific to your exact device (other manufacturers may use the same driver so long as their hardware all uses the same chipset).

Someone with your particular hardware may be able to tell you what driver(s) is required.

After I build the kernel by running (the urgly way)

make Image
make modules

I find the Image is at

my_build_location/arch/arm64/boot/Image

Is this Image the correct one to copy to /boot? Why it is arm64?

I am building the kernel for CONFIG_LOGITECH_FF. If I set CONFIG_LOGITECH_FF=y in the .config. I only need to build the Image and copy the Image to /boot/. I do not need to build and copy modules. Correct?

The last 32-bit Jetson was the TK1. All of the Jetsons after this (so far) are 64-bit. They are also ARM, and so this is “arm64/aarch64/ARMv8-a”. “arm64” is the CPU architecture of a TX2 and similar Jetsons.

I would suggest keeping the original file safe, but yes, you would copy this to “/boot” of the Jetson.

FYI, if you were to build this instead as a module format (not all drivers allow this though), then you could simply copy the one module and there would be a lot less risk. If something goes wrong after copying an Image file, then the system might not be bootable. If there is anything important on this system, then I will recommend first cloning. It is trivial and fast (once you have a clone) to restore, and for example, to update the Image on the clone prior to flash so that there is very little risk.

Note that if your CONFIG_LOCALVERSION changed, then you would also need to copy all o the modules. Normally this is it:
CONFIG_LOCALVERSION="-tegra"

Modules are searched for at:
/lib/modules/$(uname -r)/kernel/

If the base kernel name and CONFIG_LOCALVERSION match between the two kernels, then modules will already be there. Assuming your basic configuration matches the original kernel, followed by adding a new feature, then all of the old modules should “just work” if found correctly. If you modified the kernel config too much (usually not a problem), then it might be possible you actually need a new CONFIG_LOCALVERSION and a rebuild of all modules. If you add the feature as a module, then you will never need to add the Image, nor would you need to worry about other modules.

Thanks. Because I only care about enabling Logetech Gamepad F710, how do I know which module to copy and how and where to copy?

You should make sure the full kernel config is in place, and then use something like “make nconfig” so you can search for that symbol, and use the “m” key to set to module format. Even if you are only making a module I recommend acid testing by seeing if the full kernel can be built, then “make modules”. Not sure how much of the build you are used to, but typically you would also use “O=/some/where” for an alternate output location (in which case you would use that in every “make” command…there is also an alternate output location for “modules_install” target, e.g., “make O=/some/where modules_install INSTALL_MOD_PATH=/some/where/else”).

The trick is that not all features can be created as a module, and you should use a menu editor to make the changes to include or exclude a feature. Using “=m” with an editor will work if you know exactly what dependencies are there and that the feature can be module format, but an editor is more reliable and you won’t have to second guess if you got it all right. I tend to use “make nconfig” because it has the ability to search for symbols (such as CONFIG_LOGITECH_FF).

If you used “make O=/some/where modules_install INSTALL_MOD_PATH=/some/where/else”, then you can pick from “find /some/where/else *.ko” (or just browse around in “/some/where/else”…make sure the path is there and empty before you start).

If there are two new features, and those features are in module format, then it implies you will copy two “.ko” files somewhere into your system’s “/lib/modules/$(uname -r)/kernel/”, and you’ll be done after a reboot (or “sudo modprobe -a”). It would be quite rare for adding modules like this to cause a system boot failure, it is fairly safe.

As for the location, consider where the module is output in the “/some/where/else”, and the subdirectory will match somewhere into “/lib/modules/$(uname -r)/drivers”. If you were looking at the original source code, then the module output location mirrors that subdirectory in the actual kernel source. You can always ask for more details if you get a specific question.

I realize I am missing something important here. What is “make nconfig” and what is “menu editor”?

The Linux kernel compile uses “make”. “'make” itself has different targets (all by itself this is some default target). When you are working on kernel source and run “make nconfig” (or “make menuconfig” or “make xconfig” or any number of optional editors), then a menu based editor pops up. That editor is “smart” as to kernel options and knows to find and modify other features as needed when changing a feature is dependent upon other features. A menu editor will also refuse to set a feature to module or integrated format if that format is not supported.

Normally on command line you would use commands you’ve already seen, e.g., “make Image” or “made modules”. Try it with “make nconfig” (if you use other options, e.g., an “O=/some/where” be sure to include those options too).

When building a kernel or kernel module natively on a Jetson this would require you to have first installed the ncurses dev software:
sudo apt-get install libncurses5-dev

You will see some hot key options at the bottom of the application for things like saving or finding a symbol. Most of the time you would put a starting “.config” file in place, possibly via extracting from a running system or possibly via “make tegra_defconfig” (an example of another “make” target). When nconfig (or any editor) starts it will being by populating with the current “.config”. Saving will save the “.config”. Once this is done you are ready to build various parts of a kernel.

I ran “make nconfig” and searched for “CONFIG_LOGITECH_FF”, it showed:

Symbol: LOGITECH_FF [=n]                                  │       │
Defined at drivers/hid/Kconfig:452                      │       │
Depends on: INPUT [=y] && HID [=y] && HID_LOGITECH [=y] │        
Selects: INPUT_FF_MEMLESS [=n]

This means I have to change .config and make

CONFIG_INPUT=y
CONFIG_HID=y
CONFIG_HID_LOGITECT=y
CONFIG_LOGITECT_FF=y

and built Image. Correct?

This also means that I can not build module. Correct?

What does “Selects: INPUT_FF_MEMLESS [=n]” mean?

Correct. But if you are at that symbol, then the “m” key sets to module format, the “y” key sets to integrated, the “n” key sets to “no” (which it already is). You don’t need to set that with another editor, just use the hot key in nconfig and it’ll change it for you. Before exiting do a save. Use “=m” and not “=y” so you can use module format, it will simplify your life. If nconfig does not allow the setting with “m” key, then it isn’t possible to use module format.

NOTE: Config editors understand dependencies and conflicts. Setting one setting may alter other settings, and it will warn you.

I was able to build the logitech modules. However, I found the new module are much larger than the old one:

Here is the old ones:

-rw-r–r-- 1 root root 25504 Sep 29 2019 hid-logitech-dj.ko
-rw-r–r-- 1 root root 41088 Sep 29 2019 hid-logitech-hidpp.ko
-rw-r–r-- 1 root root 19832 Sep 29 2019 hid-logitech.ko

Here are the new ones:
-rw-r–r-- 1 nvidia nvidia 369312 May 14 14:22 hid-logitech-dj.ko
-rw-r–r-- 1 nvidia nvidia 452336 May 14 14:22 hid-logitech-hidpp.ko
-rw-r–r-- 1 nvidia nvidia 502032 May 14 14:22 hid-logitech.ko

However, I still do not see hid-logitech-ff.ko.

Why?

Seems I could not set CONFIG_LOGITECT_FF=m. I can only set it to y. So I only need to compile the Image and put it under /boot, correct?

@linuxdev

I did the following

  1. set the following in .config
    CONFIG_INPUT=y
    CONFIG_HID=y
    CONFIG_HID_LOGITECT=y
    CONFIG_LOGITECT_FF=y

  2. Make the Image

  3. Copy Image to /boot

  4. Reboot the Xavier.

  5. Check the /proc/config.gz, I found the logitest related config all became “m” again

CONFIG_HID=m
CONFIG_HID_LOGITECT=m
CONFIG_LOGITECT_FF=m
6. The LogiTect GamePad F710 still not working.

Why?

Modules start with debug information (which makes file size larger). To make modules smaller they can be stripped (this usually is not needed and is ok for most cases to leave the debug symbols in place). See this for stripping:
https://devtalk.nvidia.com/default/topic/1055518/jetson-agx-xavier/kernel-module-size-kernel_supplements-tbz2-has-huge-different-size-/post/5354775/#5354775
https://forums.developer.nvidia.com/t/kernel-module-size-kernel-supplements-tbz2-has-huge-different-size/76335/3

If using command line tools from the cross compiler on a host PC for stripping (“there’s more than one way to strip a cat module”):
<tool_chain_path>/aarch64-linux-gnu-strip --strip-unneeded <path-of-kernel-module.ko>


…apparently this feature must be integrated and thus you are correct to place the Image file in “/boot” (this would not be necessary if “=m” was allowed…module additions do not require replacing an entire kernel). However, one of the steps you missed (or at least did not mention) is to set CONFIG_LOCALVERSION (this is one you can directly edit in the “.config” file, but if you use a menu editor it works this way as well):
CONFIG_LOCALVERSION="-tegra"

If you have set to “=y”, and then you must also save from the menu editor prior to exiting. You can then verify what the file has via this:

egrep 'CONFIG_(HID|HID_LOGITECH|LOGITECH_FF)([=]| is not set)' /where/ever/it/is/.config

Do be careful to save a copy of the original “/boot/Image”. If you have serial console, and want to boot to an alternate Image without removing the original (you’d have to know to interrupt boot at the right moment via serial console), then you could for example:

sudo -s
cd /boot
cp Image Image-original
cp /where/ever/it/is/new/version/Image Image-logitech
# Edit "/boot/extlinux/extlinux.conf", duplicate and edit the
# "LABEL" blocks. The end of the file would look something
# like this:
LABEL primary
      MENU LABEL primary kernel
      LINUX /boot/Image-original
      APPEND ${cbootargs} root=/dev/mmcblk0p1 rw rootwait rootfstype=ext4

LABEL logitech
      MENU LABEL logitech
      LINUX /boot/Image-logitech
      APPEND ${cbootargs} root=/dev/mmcblk0p1 rw rootwait rootfstype=ext4

In serial console you will see this very early on boot, and hitting any key when this shows up drops you into the U-Boot kernel selection menu:

U-Boot 2016.07-g0eb73f4 (Mar 13 2019 - 00:20:34 -0700)

TEGRA186
Model: NVIDIA P2771-0000-500
DRAM:  7.8 GiB
MC:   Tegra SD/MMC: 0, Tegra SD/MMC: 1
*** Warning - bad CRC, using default environment

In:    serial
Out:   serial
Err:   serial
Net:   eth0: ethernet@2490000
Hit any key to stop autoboot:  0 
MMC: no card present
switch to partitions #0, OK
mmc0(part 0) is current device
Scanning mmc 0:1...
Found /boot/extlinux/extlinux.conf
Retrieving file: /boot/extlinux/extlinux.conf
213 bytes read in 115 ms (1000 Bytes/s)
p2771-0000 eMMC boot options
1:	primary kernel
Enter choice:  

If you hit a key just prior to “Enter choice:”, then you will drop into U-Boot command line, which you do not want to do. This doesn’t harm anything, but it is too early. If you do this, then simply type “boot” and enter, and then almost immediately you will get to the kernel selection menu and be able to enter a choice there instead. The “1” key would be for the original Image, the “2” key (since it is the second “LABEL” block) would run the Image-logitech.

Once you have booted you can verify the “uname -r” command still ends with “-tegra” (which is what CONFIG_LOCALVERSION sets), and that you have content at:
/lib/modules/$(uname -r)/kernel/

Then you can verify that the options were added in some form (something other than “=n”…since menu config says this can only be integrated, this means it should show “=y”…any “=m” would be invalid for your purposes since menu editor did not all “=y”):

zcat /proc/config.gz | egrep 'CONFIG_(HID|HID_LOGITECH|LOGITECH_FF)([=]| is not set)'

Incidentally, one of the reasons to use a menu editor (like “make nconfig”) is in fact to know that “=m” is not possible for some cases, and to not allow editing to become “=m” in those cases. The fact that you still see “=m” for a feature which does not allow this implies the feature probably won’t work, and could even result in kernel errors.

For all features which are “=m”, if the file path “/lib/modules/$(uname -r)/kernel/” does not exist, then all such modular features will fail (the kernel would not be able to find those files…conversely, if your “uname -r” does not change, then all old modules will be found and it isn’t necessary to install them all again).

I also did not see if you had a correct initial configuration prior to making your config editor changes. Assuming you started with the “/proc/config.gz” of the system when the original Image was running, then all is good (or if you started with “make <options> tegra_defconfig”). I’m guessing it would not have compiled if you did not do this, so you probably did have an initial start config which was valid.

I double checked, CONFIG_LOGITECH_FF depends on CONFIG_HID_LOGITECH. CONFIG_HID_LOGITECH has to be set to m, CONFIG_LOGITECH_FF has to be set to y. Then should I replace image, or the module? or both?

If anything is “=y”, then Image must be replaced. If anything is “=m” then a kernel module file must be copied in. In this case it seems like you will end up doing both.

Note that if “uname -r” changes (meaning if CONFIG_LOCALVERSION is not “-tegra” or if the base kernel version changes), then you must regenerate and install all modules, and not just add the one you are working on.

@linuxdev It worked. Thank you very much. You are the best!!!

More feekback:

  1. I found “zcat /proc/config.gz | egrep ‘CONFIG_(HID|HID_LOGITECH|LOGITECH_FF)([=]| is not set)’” still showing CONFIG_LOGITECH_FF is not set. But if I run jstest, it worked. This is confusing.

  2. I only need to copy the module hid-logitech.ko. Image was not needed.

  3. “sudo depmod -a” did not seem to work, I have to reboot.

  4. “In serial console you will see this very early on boot, and hitting any key when this shows up drops you into the U-Boot kernel selection menu” did not seem to work. I was not able to go into U-Boot.

Apparently that kernel feature is not required for jstest. It is also possible there is a module for that even if the original kernel compile did not specify this. Do make sure that anything you checked as “=y” did make it into the config.gz just to verify the Image was found. When you say you only needed “hid-logitech.ko” this does indicate that “config.gz” might not change even though a new module was added (and thus this is why the other config feature was probably not needed by jstest).

Even when depmod works for you I usually suggest reboot anyway (if you were writing and testing kernel modules then you would hate rebooting each time, but for a system being used reboot is the acid test).

Serial console should always work. The trick is that the moment when you hit the button to select kernel requires hitting a button over a very short time interval right when the kernel selection is possible. Make sure serial console allows you to type in text after booted, and if this works, then interrupting to pick a kernel in U-Boot is nearly guaranteed to work.

Hello, I’m also trying to do the same thing as @AutoCar

However, when I try to run gunzip config.gz (tried as sudo as well) I get gzip: config: No such file or directory. I also tried make nconfig CONFIG_LOGITECH_FF and make nconfig config.gz and just make nconfigall of which gave back: make: *** No rule to make target 'nconfig'. Stop.
Also when I try to extract or edit the “config.gz” file it gives an error, even when sudo. The config.gz file is also highlighted in red when viewed in the terminal via “ls” if that means anything.

Thank you!

`