udlfb

The current version of L4T build on TX1 does not have udlfb module. Any ideas on how to get it?

Thanks,
Kaan

I could be wrong, but I think what you are asking for would require the nouveau driver to function…which means giving up all hardware acceleration of video or GPU. Perhaps more information on how you want to use udlfb would help.

udlfb module is for these framebuffer devices from displaylink (USB 2.0 ones only). I can’t seem to find udlfb.ko udlfb.h or uldfb.c inside the current installation. I have found those files through Linux 3.10 kernel under Linux Kernel webpage, I am wondering if there is a way to compile them for this custom build of L4T provided with Jetson TX1 developer kit.

Framebuffer devices won’t be hardware accelerated, but it looks like udlfb module can be built by enabling kernel option CONFIG_FB_UDL.

This isn’t customized for Jetson in any way, it’s just a feature which hasn’t yet been chosen for install. Basically people get used to automatic detection and install of drivers for desktop system hardware, whereas embedded systems are pretty much manual install of everything. This means you’ll have to set up for kernel cross-compile from your desktop Linux machine, followed by some manual file copying.

If your Linux host is Ubuntu, I believe you can use existing Ubuntu packages for the cross-compile tools. I use Fedora, so I manually install the 32-bit and 64-bit tool chains. I use the latest Linaro 5.2 version…if you go that route see:
https://releases.linaro.org/components/toolchain/binaries/
…64-bit is aarch64-linux-gnu, 32-bit is arm-linux-gnueabihf.

L4T R23.2 page is:
https://developer.nvidia.com/embedded/linux-tegra

Download the kernel source from the L4T R23.2 Jetson downloads. Some information to get you started on cross-compile is here:
https://devtalk.nvidia.com/default/topic/901677/jetson-tx1/building-tx1-kernel-from-source/post/4749300/#4749300

It isn’t actually as hard as it looks, nor as complicated, but expect to need to ask more questions as you go along. You essentially install cross-compile tools, unpack and configure kernel source to match an existing/running JTX1 (including CONFIG_LOCALVERSION, the tail of what the Jetson responds with under “uname -r”, e.g., “-g458d45c”), and then add in the CONFIG_FB_UDL option as a module. This builds and you copy the module file to the correct place in your Jetson.

I see your point, and I am trying to do this on my developer kit. Do you think is there a shortcut routine rather than manually compiling (maybe through Jetpack)? If so any direction and suggestion is more than welcomed. Thank you, linuxdev!

Ok let’s start with the very basic. On an Ubuntu 14.04, I am trying to compile gcc-linaro-5.3-2015.02. I started with a simple command of

cd Downloads/gcc-linaro-5.3-2016.02

./configure

And here is the output for that:

kaan@kaan-VirtualBox:~/Downloads/gcc-linaro-5.3-2016.02$ ./configure
checking build system type… x86_64-unknown-linux-gnu
checking host system type… x86_64-unknown-linux-gnu
checking target system type… x86_64-unknown-linux-gnu
checking for a BSD-compatible install… /usr/bin/install -c
checking whether ln works… yes
checking whether ln -s works… yes
checking for a sed that does not truncate output… /bin/sed
checking for gawk… no
checking for mawk… mawk
checking for libatomic support… yes
checking for libcilkrts support… yes
checking for libitm support… yes
checking for libsanitizer support… yes
checking for libvtv support… yes
checking for gcc… gcc
checking for C compiler default output file name… a.out
checking whether the C compiler works… yes
checking whether we are cross compiling… no
checking for suffix of executables…
checking for suffix of object files… o
checking whether we are using the GNU C compiler… yes
checking whether gcc accepts -g… yes
checking for gcc option to accept ISO C89… none needed
checking for g++… g++
checking whether we are using the GNU C++ compiler… yes
checking whether g++ accepts -g… yes
checking whether g++ accepts -static-libstdc++ -static-libgcc… yes
checking for gnatbind… no
checking for gnatmake… no
checking whether compiler driver understands Ada… no
checking how to compare bootstrapped objects… cmp --ignore-initial=16 $$f1 $$f2
checking for objdir… .libs
checking for the correct version of gmp.h… no
configure: error: Building GCC requires GMP 4.2+, MPFR 2.4.0+ and MPC 0.8.0+.
Try the --with-gmp, --with-mpfr and/or --with-mpc options to specify
their locations. Source code for these libraries can be found at
their respective hosting sites as well as at
ftp://gcc.gnu.org/pub/gcc/infrastructure/. See also
http://gcc.gnu.org/install/prerequisites.html for additional info. If
you obtained GMP, MPFR and/or MPC from a vendor distribution package,
make sure that you have installed both the libraries and the header
files. They may be located in separate packages.

A new step, I installed these first:

sudo apt-get install gcc-4.8-aarch64-linux-gnu
sudo apt-get install binutils-aarch64-linux-gnu
sudo apt-get install libgmp3-dev
sudo apt-get install libmpc-dev sudo apt-get install libmpfr-dev

Then, rerun configure with:

./configure --enable-multilib

And passed the configure step without any error. Let’s see how make goes.

JetPack is a bundle of nVidia packages. JetPack has no way to compile or build kernels…you could copy a custom kernel somewhere and have this substitute what JetPack flashes, but nothing would be gained. Cross-compile on your host is close to mandatory…any steps you might make to build an environment for mixed 64/32-bit on the JTX1 would be far more difficult and slower.

Linaro provides binary pre-compiled files for recent versions…you got the source version and this is a lot of work, so I’d suggest just using the pre-made binaries, and although the 5.3 versions will work, my testing is with the latest 5.2 version. See:
Binaries in general:
https://releases.linaro.org/components/toolchain/binaries/
Latest 5.2 version:
https://releases.linaro.org/components/toolchain/binaries/5.2-2015.11-2/
32-bit Binaries:
https://releases.linaro.org/components/toolchain/binaries/5.2-2015.11-2/arm-linux-gnueabihf/
64-bit Binaries:
https://releases.linaro.org/components/toolchain/binaries/5.2-2015.11-2/aarch64-linux-gnu/

In particular, these prebuilt binaries:
https://releases.linaro.org/components/toolchain/binaries/5.2-2015.11-2/arm-linux-gnueabihf/gcc-linaro-5.2-2015.11-2-x86_64_arm-linux-gnueabihf.tar.xz
https://releases.linaro.org/components/toolchain/binaries/5.2-2015.11-2/aarch64-linux-gnu/gcc-linaro-5.2-2015.11-2-x86_64_aarch64-linux-gnu.tar.xz

These merely need to be unpacked and placed where you want them…I’d place them under:

"/usr/local/...named_after_binary_release_and_date...".

For a JTX1 I would stick to the version 5.2+ Linaro, there has been enormous improvement for ARM 64-bit since the 4.8 days. For the 32-bit Jetson TK1 I’d recommend 4.8 or 4.9 series (but native compile on a JTK1 would mean no need for cross compile).

I think I have compiled successfully, here is my log on what I have done so far. But I don’t know whatelse to do and how to insert this to my developer board either:

I tried all these on R23 version of L4T.

Get your tools for cross-compilation, on Ubuntu 14.04 by:
    Downloading gcc-linaro-5.2-2015.11-2-x86_64_aarch64-linux-gnu.tar.xz,
    Downloading gcc-linaro-5.2-2015.11-2-x86_64_arm-linux-gnueabihf.tar.xz,
    Extract them to your home folder using tar -xvf .

Get the kernel source from here.

Export your environment before compilation, here is an example from my case (Note that I have exported them to my home folder):

export CROSS_COMPILE=/home/kaan/gcc-linaro-5.2-2015.11-2-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-

export CROSS32CC=/home/kaan/gcc-linaro-5.2-2015.11-2-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc

export TEGRA_KERNEL_OUT=/home/kaan/jetson/

export ARCH=arm64

Make sure that you have the correct build directories:

make O=$TEGRA_KERNEL_OUT mrproper

Navigate to the kernel directory:

cd ~/Downloads

cd kernel

Make sure that in your kernel directory Makefile has correct KBUILD_CFLAGS_KERNEL:

KBUILD_CFLAGS_KERNEL := -fomit-frame-pointer

Fix this stupid bug by going through drivers/platform/tegra/tegra21_clocks.c in your kernel source file:

before: c->state = (!is_lp_cluster() == (c->u.cpu.mode == MODE_G)) ? ON : OFF;

after: c->state = ((!is_lp_cluster()) == (c->u.cpu.mode == MODE_G)) ? ON : OFF;

Let's create the config files under kernel directory:

make O=$TEGRA_KERNEL_OUT tegra21_defconfig

Make sure that you have the correct flag in your config file in your build directory, so that it supports displaylink framebuffer devices (only USB 2.0 versions such as this one). Simply navigate to ~/jetson/build/.config. And add this to the

CONFIG_FB_UDL=y

Let's build the kernel, and wish that everything goes well. Good luck:

make O=$TEGRA_KERNEL_OUT zImage

Execute this command to generate command tree:

make O=$TEGRA_KERNEL_OUT dtbs

Execute this command to generate driver modules finally:

make O=$TEGRA_KERNEL_OUT modules

Copy images to kernel directory, here is what I have done to copy them:

kaan@kaan-VirtualBox:~/jetson$ cp arch/arm64/boot/Image kernel/

kaan@kaan-VirtualBox:~/jetson$ cp arch/arm64/boot/zImage kernel

I do not know if CONFIG_FB_UDL allows being built as non-module, nor if there is any related dependency which would require enabling when turning on CONFIG_FB_UDL (I’m not near a machine I can test on at the moment), which is why I tend to make all such adjustments through “make O=$TEGRA_KERNEL_OUT menuconfig”.

If the “y” option is directly supported and not needing other option changes, then directly editing the .config file would be correct. CONFIG_LOCALVERSION would need to be set, and if you build FB_UDL as a non-module, then you should do a complete kernel install with a modified CONFIG_LOCALVERSION. Did you use make menuconfig to change the parameter, or did you edit the .config directly?

If you build as a module you can keep CONFIG_LOCALVERSION and copy over only a kernel module. This is recommended if possible. Parameter as “=y” implies integrated as non-module, parameter “=m” implies build a kernel module only for dynamic loading into the existing kernel. The point is that changing a config to “y” changes the base kernel…changing the config to “m” only creates a loadable module which can be loaded into a matching kernel and copied as a separate file. Not all features are available as a module, nor are all features available as an integrated non-module feature. Use menuconfig to find out.

The basics up until copy of Image file look correct.

I am bit lost with how to flash the kernel that I have compiled. I have Jetpack installed, and located flash.sh. Can you advise me on the next possible step?

By the way, menuconfig has nothing for udlfb or displaylink. Under normal conditions, there should be an item for displaylink under device drivers-> graphics support-> support for frame buffer devices

When using u-boot, no flash is required. It is just file copy. If the change is as a module format, then not even the kernel requires copy, just the module. Make sure CONFIG_LOCALVERSION is correct, see menuconfig:

General setup -> Local version

Menuconfig can be dependency-aware. If for example there is some prerequisite requirement for an option, then the option may not show up until the prerequisite is met. You can search the .config file to look for different specific config options, and if you see it there, then you know it is somewhere within menuconfig. However, some options may only exist in older or newer kernels, you may need to check kernel.org to see which versions have the option. CONFIG_FB_UDL does exist in the default JTX1 kernel source…I do not know the dependencies.

So if I am understanding you correctly. At the end of compilation, I should have something like udlfb.ko and copy it to TX1, to here maybe?

/lib/modules/3.10.67-g458d45c/kernel/drivers/video

and just trigger it using

sudo depmod -a

sudo modprobe udlfb

under TX1

Is this a correct understanding?

That is correct. Just make sure you start with a matching configuration to the existing Jetson (including CONFIG_LOCALVERSION), then add that new feature in as a module. This should produce the module file and the copy steps you gave will be correct.

OK, now I have it under menuconfig, I forgot to trigger this:

make O=$TEGRA_KERNEL_OUT tegra21_defconfig

and yes, it comes with a “m” flag rather than “y”. I compiled accordingly and installed the modules using below command:

make O=$TEGRA_KERNEL_OUT modules_install INSTALL_MOD_PATH=$TEGRA_KERNEL_OUT/modules

Found udlfb.ko from modules/lib/modules/3.10/kernel/drivers/video directory, and copied to the existing OS of TX1 devkit, copied here by the way:

/lib/modules/3.10.67-g458d45c/kernel/drivers/video

did this one:

sudo depmod -a

and reboot TX1.

tried this:

sudo modprobe udlfb

and got this:

modprobe:Error: could not insert udlfb: Exec format error

Owww owww I see what you are saying with local version

should local version be this?

-g458d45c

And the module is working finally, I only copied udlfb.ko. And did depmod. Thank you!

That would be the correct local version. So many details…individually not hard, but putting them all together to cross compile and install can take a lot of research time.

Now I wonder how to make this module load automatically when the device is plugged.