Skip to main content

How to get Debian, WiFi/WLAN and AMD graphics running on Lenovo ThinkPad E495

I was helping someone with a non-trivial installation of Debian on a Lenovo ThinkPad E495 recently. The installation was anything but straightforward so I'll quickly document what it took to get WiFi and graphics working eventually. I have an idea by now why the E495 did not receive a hardware certification from Ubuntu like other ThinkPads did.

I believe that E495 and E595 are very close with regard to hardware outside of screen size, so there is some chance that most to all of this article applies to E595 as well.

Relevant E495 hardware components

If you're wondering if your E495 is close enough to keep reading this article, our model has:

  • AMD Ryzen 7 3700U CPU with Radeon Vega Mobile Gfx "Picasso"
    Advanced Micro Devices, Inc. [AMD/ATI] Picasso (rev c1)
    Kernel modules: amdgpu
  • Realtek RTL8111/8168/8411 Ethernet Controller
    Realtek Semiconductor Co., Ltd. RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (rev 10)
    Kernel modules: r8169
  • Realtek RTL8822BE WiFi adapter
    Realtek Semiconductor Co., Ltd. RTL8822BE 802.11a/b/g/n/ac WiFi adapter
    Kernel modules: rtwpci
  • Realtek RTL8822B Bluetooth Radio

The details were extracted from output of lspci -k in the running system. The Bluetooth hardware not attached through PCI but internal USB.

What made the installation difficult?

  • Out of the box Debian buster is too old for recent hardware like this one (so we went for bullseye)
  • Even bullseye firmware packages are to outdated to contain all needed files
  • The bullseye installer is buggy (so it takes installing buster first and doing a dist-upgrade)
  • We saw nasty rendering artifacts in XFCE (before we adjusted xfwm4 configuration)
  • Some menu entries would not open (but have XFCE complain about lack of qdbus)
  • With secure boot enabled, WiFi will list available networks and pretend to be connected but it won't serve any actual traffic. Ouch.

The approach to installation that worked

Before we start, please make sure you have secure boot disabled in the BIOS or at least WiFi will not be fully functional.

So we start by installing Debian buster; it takes a working Ethernet connection and using a USB stick flashed with the Debian buster netinst ISO, e.g. debian-10.3.0-amd64-netinst.iso. During installation we do not select any desktop environment so we do not end up in a broken Xorg session but the terminal, after reboot.

After the installation, we mass-replace buster by bullseye in /etc/apt/sources.list, e.g. with sed -i 's,buster,bullseye,g /etc/apt/sources.list' and do a dist upgrade, e.g. by apt update ; apt dist-upgrade -V. One of the downloads of apt update will fail because bullseye is not released yet but that's okay. On a side note, we went for bullseye rather than testing here because bullseye will stop moving at some point in the near future while testing will remain rolling all the time.

What more do we need now?

  • some firmware files
  • the right Xorg driver package
  • a desktop environment
  • (a config change of xfwm4 in case of XFCE)

Let's start with firmware.


If the related packages in Debian were complete and recent, you would need:

How do I know which firmware files are needed? The kernel knows which hardware needs which firmware file and the kernel log tells us which firmware files it loads or failed loading. In working E495 system it looks like this:

# sudo dmesg | fgrep direct-loading
[    1.768139] amdgpu 0000:05:00.0: firmware: direct-loading firmware amdgpu/picasso_gpu_info.bin
[    1.768281] amdgpu 0000:05:00.0: firmware: direct-loading firmware amdgpu/picasso_sdma.bin
[    1.770323] amdgpu 0000:05:00.0: firmware: direct-loading firmware amdgpu/picasso_asd.bin
[    1.770364] amdgpu 0000:05:00.0: firmware: direct-loading firmware amdgpu/picasso_ta.bin
[    1.770391] amdgpu 0000:05:00.0: firmware: direct-loading firmware amdgpu/picasso_pfp.bin
[    1.770412] amdgpu 0000:05:00.0: firmware: direct-loading firmware amdgpu/picasso_me.bin
[    1.770427] amdgpu 0000:05:00.0: firmware: direct-loading firmware amdgpu/picasso_ce.bin
[    1.770456] amdgpu 0000:05:00.0: firmware: direct-loading firmware amdgpu/picasso_rlc.bin
[    1.770582] amdgpu 0000:05:00.0: firmware: direct-loading firmware amdgpu/picasso_mec.bin
[    1.770687] amdgpu 0000:05:00.0: firmware: direct-loading firmware amdgpu/picasso_mec2.bin
[    1.772470] amdgpu 0000:05:00.0: firmware: direct-loading firmware amdgpu/raven_dmcu.bin
[    1.772592] amdgpu 0000:05:00.0: firmware: direct-loading firmware amdgpu/picasso_vcn.bin
[  116.581265] platform regulatory.0: firmware: direct-loading firmware regulatory.db
[  116.581427] platform regulatory.0: firmware: direct-loading firmware regulatory.db.p7s
[  116.828475] rtw_pci 0000:04:00.0: firmware: direct-loading firmware rtw88/rtw8822b_fw.bin
[  116.991964] bluetooth hci0: firmware: direct-loading firmware rtl_bt/rtl8822b_fw.bin
[  116.992154] bluetooth hci0: firmware: direct-loading firmware rtl_bt/rtl8822b_config.bin
[  117.098348] r8169 0000:02:00.0: firmware: direct-loading firmware rtl_nic/rtl8168g-3.fw

The source of all of these files is the linux-firmware upstream Git repository.

Let's see how recent these very firmware files are in the upstream Git today (as of 2020-05-04):

# git clone -c fetch.fsckObjects=False \
# cd linux-firmware
# for i in $(ls -1 amdgpu/picasso_* \
                   rtw88/rtw8822b_fw.bin \
                   rtl_bt/rtl8822b_*.bin \
                   rtl_nic/rtl8168g-3.fw); do \
    echo "$(git log --format=%as -n1 -- "$i") $i" ; done | sort
2013-04-23 rtl_nic/rtl8168g-3.fw
2017-04-14 rtl_bt/rtl8822b_config.bin
2017-04-14 rtl_bt/rtl8822b_fw.bin
2018-10-04 rtw88/rtw8822b_fw.bin
2018-12-13 amdgpu/picasso_gpu_info.bin
2018-12-13 amdgpu/picasso_sdma.bin
2019-04-26 amdgpu/picasso_rlc_am4.bin
2020-01-06 amdgpu/picasso_ce.bin
2020-01-06 amdgpu/picasso_mec2.bin
2020-01-06 amdgpu/picasso_mec.bin
2020-01-06 amdgpu/picasso_pfp.bin
2020-01-06 amdgpu/picasso_rlc.bin
2020-01-06 amdgpu/picasso_vcn.bin
2020-04-16 amdgpu/picasso_asd.bin
2020-04-16 amdgpu/picasso_me.bin
2020-04-16 amdgpu/picasso_ta.bin

For the AMD firmware files, all but amdgpu/picasso_ta.bin are contained in package firmware-amd-graphics but Debian most recent 20190717-2 does not have up-to-date versions. For the Realtek firmware files, all but rtw88/rtw8822b_fw.bin are included with latest version 20190717-2 of firmware-realtek in Debian.

So we'll copy files from Git into /lib/firmware/ manually. Make sure to keep the directory structure, e.g. copy amdgpu/picasso_ta.bin to /lib/firmware/amdgpu/picasso_ta.bin.

To get the firmware loaded, you either need to reload selected kernel modules — at least amdgpu, r8169, rtwpci, rtw88 — or just do a quick reboot. I recommend going for the latter, for simplicity.

Xorg and desktop environment

Now that we have the firmware files around, let's install packages xserver-xorg-video-amdgpu and libgl1-mesa-dri so that Xorg has the right drivers. In case you don't get a picture but a hanging Xorg later, inspecting log file /var/log/Xorg.0.log may help.

Adding a desktop environment can easily by done by sudo tasksel: you'll get the same experience as inside the Debian installer.

In case you choose XFCE like us and experience weird graphic artifacts like these, our fix was running…

# xfconf-query -c xfwm4 -p /general/vblank_mode -t string \
    -s xpresent --create
# pkill xfwm4

as learned from this forum post by mbod. The added pkill xfwm4 kills the current instance of xfwm4 so that XFCE starts a new one that respects our change in configuration.

To teach XFCE how to open desktop menu items just install qdbus-qt5 and it should work.


If you cannot get it to work, feel free to get in touch.

Some closing notes:

  • Stable distributions and recent hardware are not a good match.

  • Command line tool efibootmgr can be of great help with debugging or changing EFI boot entries and boot order from within a running system.

  • Command like tool mokutil can be of help checking if secure boot is enabled, without a reboot.

Best, Sebastian