You are correct that you need the kernel module. If the kernel were stock, then you could do this (but it won’t work on a Jetson):
sudo apt-get install "linux-kernel-modules-extra-$(uname -r)"
…and the reason this is unlikely to work is that the kernel version and its “uname -r
” are not normally available from stock Ubuntu repositories. I suppose if NVIDIA built these and put them on its server, then it would work.
The whole reason this is needed is that there are a lot of different character sets out in the wild, and normally only some default is installed. For example, not many people will end up with Sanskrit, so why install it if not using it?
So you do need to custom compile this module. The reason you are probably having trouble is that the source code configuration must match your running system in order to use the module with your system.
There are several places describing kernel module build, but getting configuration correct is not always obvious. For example, the official docs on cross compiling are thorough if you are installing everything, but not so obvious if you are making just a module to match a given kernel. So here are some random facts to help (random because you will probably need to know this, but the location and timing of using the information varies):
- When you “
make tegra_defconfig
” you are configuring the kernel. That configuration is a sane default and mostly matches any unmodified default install. However, you still need to take into account “CONFIG_LOCALVERSION
”.
- Any configuration created from a “
make tegra_defconfig
” is reflected in the “.config
” file of the root of the kernel source.
- You are better off creating your default “
.config
” by asking the Jetson what its actual config is. If there are any changes, then your config will be an exact match which tegra_defconfig
won’t catch. You still need to edit “CONFIG_LOCALVERSION
”, and this is true regardless of whether you compile based on tegra_defconfig
or asking the running Jetson what its config is. To get this configuration you would copy “/proc/config.gz
” somewhere safe (keep a copy), gunzip config.gz
", edit “CONFIG_LOCALVERSION
” to:
CONFIG_LOCALVERSION="-tegra"
…and then copy this to your kernel build location with name “.config
”.
- Even if you build only a module it is a good “sanity check” to build the “
Image
” target first. There are shortcuts to propagating configuration when building just modules, but I recommend not using those shortcuts until after the “Image
” (full kernel) target has been built once.
So the short list is:
- Get the official docs on kernel build.
- Build the base kernel
Image
even if you don’t need to. You could skip this and instead shorten time of build with “make modules_prepare
” prior to building modules, but if you do so, then you lack one sanity test of your configuration.
- Place a copy of the gunzip’d “
/proc/config.gz
” on your host, and skip the “make tegra_defconfig
”. Copy the gunzip’d and edited (for “CONFIG_LOCALVERSION
”) in your output build directory for the kernel build (probably docs will mention setting an environment variable “TEGRA_KERNEL_OUT
”…this is the build location, and is different than the source location).
- Either “
make Image
” or “make modules_prepare
” (both will propagate config for module build). “Image
” is preferred since failures will show up. Only needs to be done once.
- “
make modules
”.
After you build, at your “$TEGRA_KERNEL_OUT
” location, there will be a subdirectory:
fs/nls/
…within this there will be content for each module built, and in your case (probably…I didn’t actually build this):
fs/nls/nls_utf8.ko
BIG note: Everything I’ve mentioned already has been for building an exact match to your running system. You still need to edit the config to build “nls_utf8.ko
”. I recommend using “make nconfig
” (after setting up the matching “.config
”), but most docs will show using “make menuconfig
”. The two commands will require first “sudo apt-get install ncurses5-dev
”. I use “nconfig
” because it has a “symbol search” function. You could for example search for “utf8
”, and then enable this in the form of a module (the “m
” key for selection in “make nconfig
” or “make menuconfig
”. This simplifies using the editor to find particular features. Once this is done you can perform the actual compile. Any “Image
” created would be an exact match to your running system, and any modules created would be an exact match with the exception of now also having the nls_utf
feature as a module.
You can always ask more questions, but you can get started if you go to the docs for your specific L4T release and then looking at “kernel customization”. Your L4T release can be found by “head -n 1 /etc/nv_tegra_release
”. The URL where you can find each L4T release (and then navigate to its docs) is here:
https://developer.nvidia.com/linux-tegra
Btw, it is actually much simpler in practice if you’ve done this once. Don’t let it scare you. The module install is really just a copy of a single file once done. I’ve added a lot of details based on what tends to fail based on tiny details.
Also, official docs will be for cross compile…building on the host PC for install to the Jetson. There are several environment variables mentioned there…you don’t need those for a native compile, but do for cross compile. If I’ve mentioned “make tegra_defconfig
”, then this is the same (other than environment) as what the docs will show as “make O=$TEGRA_KERNEL_OUT tegra_defconfig
”. The environment variables are just for finding things or for keeping clutter of temporary content someone other than in the pristine source code. Feel free to ask questions.