You always start with a full kernel config that matches your running system. One possibility is by using the default config. For JetPack 6.x/L4T R36.x, that is “mostly” the “defconfig” target. You would also need to set your “CONFIG_LOCALVERSION” (if you are only adding modules, then use “-tegra”; if you are changing integrated features, then you probably need to completely build the kernel and all modules and change the CONFIG_LOCALVERSION to something like “-new”).
Your error is because you have a feature that was built depending on another feature, and the other feature is missing. menuconfig (and nconfig) is designed to understand dependencies. This allows you to do things like add the 5G module and automatically include dependencies.
Are you adding this as a module and keeping the rest the same? Or are you changing the base kernel?
Thanks a lot @linuxdev
Now it is making more sense.
I just want to add modules for 5G support and keep the rest of the things same.
We have a custom carrier board, so I want to modify the device tree configuration.
For the kernel then, just reuse the original. Configure to match the running system, keep the -tegraCONFIG_LOCALVERSION.
Note that a running Jetson kernel will also have the config in “/proc/config.gz”. If anything is customized, then this will still reflect the running kernel, whereas defconfig could begin diverging. Just copy config.gz somewhere, gunzip it, and rename to .config. Edit the “CONFIG_LOCALVERSION” to “=-tegra” since you are keeping the original kernel Image. Note that CONFIG_LOCALVERSION is never reflected in the “/proc/config.gz”.
Device tree is not actually part of the kernel, and this probably won’t change unless something in your 5G is not “plug-n-play”. USB devices tend to not use a device tree to upload firmware; similar for PCIe.
Regarding device trees, you can think of those more or less as an argument passed to drivers. One of the biggest uses of device tree is to simply tell a driver what physical address to find a device at when the device cannot self-report. Because each device tree node more or less only applies to a given kernel feature (or symbol), it is convenient to make device tree compile available with the kernel source using the configuration of the kernel you are building. Because the kernel and device tree have a common configuration they are packaged together. You do not normally need to build a device tree though.
Example: USB device gets a new module; or even is integrated into the kernel. No device tree change is needed since USB does the self-reporting work. The udev mechanism is the part of the USB which modifies USB devices for customization, but this would not be a device tree edit.
Example: A network device is added as a module. Network devices very often require firmware due to hardware complying with local regulations needing that firmware for the particular region of the world it runs in. The firmware in this case is not the device tree. This firmware is uploaded into the network device itself, and is agnostic to the host platform’s architecture. Regardless of whether the drivers know where this device is via plug-n-play of USB or PCIe, the device tree won’t change. However, if this is a 5G device wired directly to a bus or memory controller of the board, and there is no plug-n-play mechanism, then you would need a device tree edit. The 5G firmware would not care about the device tree, and would “just work” regardless of whether the device is discovered through self-reporting or device tree.
Is this 5G wired to a bus or memory controller? Or is it using some plug-n-play environment that can find the device just by plugging it in?
I had to change the device tree as some USB 2.0 companion for one of the USB 3.0 port was changed in the custom carrier board i am working with.
5G module can work with PCIe or USB bus. on the cutom carrier board, it is connected to PCIe. It is also plug-n-play as the device shows up lspci without any changes.
The problem here was that the check the 5G driver module does while compiling was getting confused due to the following issue.
static struct rmnet_nss_cb __read_mostly *nss_cb = NULL;
#if defined(CONFIG_PINCTRL_IPQ807x) || defined(CONFIG_PINCTRL_IPQ5018) || defined(CONFIG_PINCTRL_IPQ8074)
//#ifdef CONFIG_RMNET_DATA //spf12.x have no macro defined, just for spf11.x
#define CONFIG_QCA_NSS_DRV
/* define at qsdk/qca/src/linux-4.4/net/rmnet_data/rmnet_data_main.c */ //for spf11.x
/* define at qsdk/qca/src/datarmnet/core/rmnet_config.c */ //for spf12.x
/* set at qsdk/qca/src/data-kernel/drivers/rmnet-nss/rmnet_nss.c */
/* need add DEPENDS:= kmod-rmnet-core in feeds/makefile */
extern struct rmnet_nss_cb *rmnet_nss_callbacks __rcu __read_mostly;
//#endif
#endif
CONFIG_PINCTRL_IPQ8074=y this was set to y causing it to think it is a Qualcomm IPQ device.
when i check the platform support in the default config, i found this.
To follow up and explain, not in any particular order…
Not all kernel symbols can be built-in. Not all kernel symbols can be a module. Most can. An example of a symbol which cannot be a module is virtual memory (swap space) since it is so invasive. The dependency-aware editor (e.g., menuconfig or nconfig) knows about this, and will only let you select as module (M) or as integrated (*) if that is the case. If a symbol needs other symbols, then this too will cause the seemingly unrelated symbols from being activated when enabling the parent feature which has child dependencies.
If you are able to unselect a feature and keep the feature you are interested in, then it is perfectly valid so long as it doesn’t remove some other symbol that depends on it. You’re likely ok with removing that. In fact, unused symbols tend to waste memory and disk space, and can slow the kernel down (not by a lot, but the scheduler with a smaller table of symbols sorts faster).
If you are using a desktop PC, then there are so many different devices which are common, and yet many individuals won’t use them, that those features are just included as a module. On an embedded system this tends to not occur as much. In JetPack 6 the embedded kernel is not used, and instead the mainline kernel is used. Many of the selections are no longer from NVIDIA, but are the result of what mainline thinks is commonly used. Perhaps the feature cannot be a module (I don’t know), and this would be a reason for making the feature an integrated (*) feature instead of a module (M). Removing this feature removes the need of many dependencies it seems (the undefined symbols are maybe a requirement of the feature/symbol you disabled).
Generally speaking, the mainline kernel will need more adjustments for the best kernel config, but will include more features. If those features are not included, then it is the result of the mainline kernel and not NVIDIA. I think that in the end more people will be rebuilding the kernel with various tweaks for the JetPack 6 release than for earlier releases; earlier releases mainly get features added, newer mainline releases will tend to get both additions and removals when tweaking.