Install Lenovo ThinkPad USB 3.0 Dock on CentOS 7 (DisplayLink Adapter)

OK, this is a nice and tricky one. The dock contains a DisplayLink chipset that is not natively supported on the OS. Initially DisplayLink were trying to figure out how to get the DRMS working on open source platforms without disclosing the mechanism. Finally they released an Ubuntu version. CentOS is not supported (or DisplayLink says: go, port it yourself. So this is what we are trying to do here). These are the high level steps (note, these are minimum versions):

1. Update the kernel to minimum 3.16

2. Compile GCC 5.1 to get an updated libstdc++

3. Install EVDI

4. Install the Display Link driver.

 

 

Let's get started:

1. Updating the kernel

A newer kernel is required for evdi to work. I was not able to ad hoc compile a newer kernel and keep other devices working properly (I had issues where bluetooth does not start automatically after a suspend). So I will pick the easier and faster option: Get the long term support kernel from the elrepo repository:

yum -y install http://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm #Install the elrepo repository. Maybe find the latest elreop-release file from their website
yum --enablerepo=elrepo-kernel -y install kernel-lt kernel-lt-devel # enable the kernel disto only for this installation and install the kernels
grub2-set-default 0 # Set the new kernel as default boot (you would have to do this after every update)
grub2-mkconfig -o /boot/grub2/grub.cfg
reboot # boot into the new kernel

2. Compile GCC 5.1 to get an updated libstdc++

GCC 5.1 is required. Otherwise you get these error messages when starting the displaylink driver:

./DisplayLinkManager: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by ./DisplayLinkManager)
./DisplayLinkManager: /lib64/libstdc++.so.6: version `CXXABI_1.3.8' not found (required by ./DisplayLinkManager)
./DisplayLinkManager: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by ./DisplayLinkManager)


Note not to update the OS GCC version or you will get into quite a lot of difficulties...

yum install -y gmp-devel mpfr-devel libmpc-devel gcc-c++ gcc # install prerequisites
cd /tmp
wget ftp://ftp.gnu.org/gnu/gcc/gcc-5.1.0/gcc-5.1.0.tar.gz # download the source gcc
tar -xf gcc-5.1.0.tar.gz
mkdir gcc-build # gcc compilation requires a separate build directory.
cd gcc-build
../gcc-5.1.0/configure --disable-multilib --prefix=/opt/gcc-5.1.0 --enable-languages=c,c++ # Create the Makefile and set the installation directory to /opt/gcc-5.1.0
make -j6 # this compiles gcc. It will take some time (hrs...) -j6 uses 6 threads to compile
make install # this compiles gcc. It will take some time (hrs...)

Here we go. We now have a GCC 5.1 in /opt.

3. Install the EVDI driver
You don't have to do this manually. The DisplayLink Driver does it for you! SKIP TO 4.
## Compile EVDI
cd
mkdir git
cd ~/git
git clone https://github.com/DisplayLink/evdi.git
cd ~/git/evdi
make
#modprobe sysimgblt
#modprobe sysfillrect
#modprobe syscopyarea
#insmod module/evdi.ko # temporary install, not automated

4. Install the Display Link driver.

Download the Ubuntu driver directly from the DisplayLink homepage: http://www.displaylink.com/downloads/ubuntu

 

untar and install it with ./displaylink.sh
this should work without any issues. Note that you will not be able to run ./Displaylink because it will use the system default GCC libraries. To use our GCC version, you have to include it in the library path by putting in:
export LD_LIBRARY_PATH=/opt/gcc-5.1.0/lib64

We won't do this here as this is not required. Follow the instructions below.

# Update the displaylink service to use our GCC library
cat >> /usr/lib/systemd/system/dlm.service << EOF
Environment=LD_LIBRARY_PATH=/opt/gcc-5.1.0/lib64;
EOF
systemctl daemon-reload

# Update the xorg configuration to force an intel driver and other tweeks. If you don't force the intel driver, you will get a blank screen on the external display or it freezes otherwise.

cat > /etc/X11/xorg.conf.d/20-displaylink.conf << EOF
Section "Device"
    Identifier "intel"
    Driver "intel"
    Option "kmsdev" "/dev/dri/card0"
    Option "PageFlip" "off"
    Option "SWCursor" "on"
    Option "ShadowFB" "true"
EndSection

Section "Device"
    Identifier "USB3"
    BusID "USB"
    Driver "intel"
    Option "kmsdev" "/dev/dri/card1"
    Option "PageFlip" "off"
    Option "SWCursor" "on"
    Option "ShadowFB" "true"
EndSection

Section "Device"
    Identifier "USB3"
    BusID "USB"
    Driver "intel"
    Option "kmsdev" "/dev/dri/card2"
    Option "PageFlip" "off"
    Option "SWCursor" "on"
    Option "ShadowFB" "true"
EndSection

Section "Device"
    Identifier "USB3"
    BusID "USB"
    Driver "intel"
    Option "kmsdev" "/dev/dri/card3"
    Option "PageFlip" "off"
    Option "SWCursor" "on"
    Option "ShadowFB" "true"
EndSection
EOF

reboot

Now you are done. It should all work now.