Advanced linux configuration for Lenovo ThinkPad X240

After setting up a basic archlinux installation on a Lenovo ThinkPad X240, you now have an empty archlinux system.

You may not know it now, but some parts of your linux system are not working.

Theses coming steps are meant to configure your X240 so that it plays well with your new linux system.

It should also provide tips for other ThinkPads like the T440.

It's a list of issues I struggled to solve. I thought it would be a good idea to share them.

This post was not made to give you a working graphical and developer environment.

If you are interested in my own graphical and developer environment setup, please see my setup.

I am using archlinux so commands will include archlinux specifics. Some tips will be useful to other linux systems, like audio setup.

I expect you to be connected as root for this tutorial.

What we are going to fix

  • add yaourt pacman frontend
  • use ntp for date and time
  • working audio
  • slow dhcpcd service
  • power managment
  • add hibernate and resume functionnality
  • fix brightness and volume keys

Yaourt

Yaourt is a pacman frontend that can build and install Arch User Repository packages easily.

It has the same command line API than pacman and thus is very easy to use.

Add the archlinuxfr repository to pacman configuration, at the bottom of the file /etc/pacman.conf:

[archlinuxfr]
SigLevel = Never  
Server = http://repo.archlinux.fr/$arch  

Then we install yaourt:

pacman -S yaourt  

Date and time

Your current date and time is not automatically updated using internet services, let's do it.

We can use ntp to solve this.

date  
pacman -S ntp  
systemctl enable ntpd.service  
systemctl start ntpd.service  

Here you go, you'll never be late (or living in the future) again.

Sound

Sound was not working for me. I was surprised because soud usually works by default, it did worked by default back on the X230 I had on archlinux.

Alsa is installed by default on the archlinux system.

I discovered that the X240 had two sound card detected. One for the laptop, the other one for the mini displayport audio output.

Alsa works by trying to send the sound to the "default" sound card.

The default sound card in my case was detected as the HDMI output, bad luck.

After struggling a lot, I came up with a great solution to solve the sound problem on the X240.

The audio test

Let's first try to play some sound without any particular configuration.

pacman -S alsa alsa-utils alsa-plugins  
speaker-test -c 2 -t wav -l 1  

You should hear "Front left" followed by "Front right".

If it works, great, the default sound card is the laptop sound.

But even if it works, I advise you to do the steps bellow because the default sound card seems to be able to change over time.

Setting the right default sound card

The X240 has two sound cards, as you can see when looking at the output of:

lspci -nn | grep -i audio  
# 00:03.0 Audio device [0403]: Intel Corporation Haswell-ULT HD Audio Controller [8086:0a0c] (rev 0b)
# 00:1b.0 Audio device [0403]: Intel Corporation 8 Series HD Audio Controller [8086:9c20] (rev 04)

As for me, the default sound card I needed to set was the second one.

To do this, create a file named /etc/modprobe.d/alsa-base.conf:

# PCH
options snd-hda-intel index=0 model=auto vid=8086 pid=9c20  
# HDMI
options snd-hda-intel index=1 model=auto vid=8086 pid=0a0c  

The vid and pid numbers refers to the 8086:0a0c and 8086:9c20 pairs. Those are identifiers.

Then the index=0 means "Set this card as card0, manually", so that alsa will always pick this sound card and not the HDMI one as the default card.

I did not try to get some sound when using the displayport. I will certainly do soon and then get back to you.

Slow dhcpcd service

Dhcpcd service will always try to get the nameservers from the router and will then write and overwrite the /etc/resolv.conf file. This slow down boot time.

You can see what's taking time to boot by issuing:

systemd-analyze  
systemd-analyze blame  
systemd-analyze critical-chain  

BTW, I find systemd-analyze amazing. It can even generate graphs.

If all you want to use is some DNS servers that will always be the same, you can add them to /etc/resolv.conf and then configure dhcpcd.service.

In /etc/dhcpcd.conf, add:

nohook resolv.conf  

Then the dhcpcd.service will no more try to write DNS nameservers to /etc/resolv.conf resulting in faster startup time.

Power management

Lenovo ThinkPad X240 comes with two batteries. I use TLP, it provides me very strong defaults to keep my power when I need it.

It was designed with some specific features for Thinkpads. And offers a very good solution for any linux-based laptop.

Install it:

yaourt -Rns laptop-mode-tools  
yaourt -S tlp acpi acpid tp_smapi acpi_call  

Configure battery charge thresolds:

perl -pi -e 's/#START_CHARGE_THRESH/START_CHARGE_THRESH/g' /etc/default/tlp  
perl -pi -e 's/#STOP_CHARGE_THRESH/STOP_CHARGE_THRESH/g' /etc/default/tlp  

Start and activate tlp services:

systemctl enable tlp.service  
systemctl start tlp.service  
systemctl enable tlp-sleep.service  
systemctl start tlp-sleep.service  

Here you go, you now have a working power saving service optimized for your laptop and ThinkPad.

With this setup, I can get as much as 20+ hours of battery (verified).

Configuring hibernate and resume

I love the concept of hibernating: putting the machine in a very low power saving mode while keeping your whole environment ready to be reactivated at any moment.

I use hybrid hibernating (suspend to both) which save the system state in both RAM and disk.

When waking up, it's fast (RAM) and if you completely run out of power, you can still recover (Disk).

First, install the polkit package which will let non-root users to restart/stop the machine:

yaourt -S polkit  

Then, add the resume hook to /etc/mkinitcpio.conf:

perl -pi -e 's/block filesystems/block resume filesystems/g' /etc/mkinitcpio.conf  
cat /etc/mkinitcpio.conf  
# check results

resume hook must be placed after the block hook. Otherwise linux kernel can't find your swap resume partition at boot.

Re-create the reinitial ramdisk environment:

mkinitcpio -p linux  

We also need to inform the kernel where to look for resume images when waking up.

Find the swap partition UUID:

sudo blkid  

We see:

/dev/sda3: UUID="00930d16-b574-4bc6-b768-df60b087350c" TYPE="swap" PARTUUID="94542dbf-a7e4-426a-8aa4-f2fefb132e65"

00930d16-b574-4bc6-b768-df60b087350c is the UUID we are looking for. Let's put this UUID in the resume kernel parameter.

I use rEFInd as my boot loader. So I edit /boot/refind_linux.conf and add:

"Boot with standard options [...] resume=UUID=00930d16-b574-4bc6-b768-df60b087350c"  

Reboot. Then test your setup with:

systemctl hybrid-sleep  

It should put your system in hybrid hibernation. Wake it up by pressing the power button.

Volume and brightness keys

The volume and brightness keys were not working and I use them a lot.

The brightness keys did work but veryyyy slowly, not very good.

The volume keys were not working at all.

To solve both, install necessary packages:

yaourt -S xorg-xbacklight alsa-utils xbindkeys  

We are going to use xbacklight to set the brightness of your desktop.

We will use amixer to adjust sound.

Xbindkeys will then be used to bind the right keys to the right action.

To make things easier, we will create two scripts, sound.sh and brightness.sh that will be the glue between xbindkeys and amixer or xbacklight.

~/bin/sound.sh

Create a file at ~/bin/sound.sh

See it on github.

Kudos to ri from archlinux forums post.

#!/bin/bash

# Configuration
STEP="10"    # Anything you like.  
UNIT="dB"   # dB, %, etc.

# Set volume
SETVOL="/usr/bin/amixer -qc 0 set Master"

case "$1" in  
    "up")
          $SETVOL $STEP$UNIT+
          ;;
  "down")
          $SETVOL $STEP$UNIT-
          ;;
  "mute")
          $SETVOL toggle
          ;;
esac

# Get current volume and state
VOLUME=$(amixer get Master | grep 'Mono:' | cut -d ' ' -f 6 | sed -e 's/[^0-9]//g')  
STATE=$(amixer get Master | grep 'Mono:' | grep -o "\[off\]")

# Show volume with volnoti
if [[ -n $STATE ]]; then  
  volnoti-show -m
else  
  volnoti-show $VOLUME
fi

exit 0  

~/bin/brightness.sh

Create a file at ~/bin/brightness.sh

See this script on github.

#!/bin/bash

STEP="10"    # Anything you like.

# Set volume
INC="/usr/bin/xbacklight -inc"  
DEC="/usr/bin/xbacklight -dec"

case "$1" in  
  "inc")
          $INC $STEP
          ;;
  "dec")
          $DEC $STEP
          ;;
esac  

~/.xbindkeysrc

Create a file at ~/.xbindkeysrc.

See this file on github.

# Increase volume
"sh $HOME/bin/sound.sh up"  
    m:0x0 + c:123
    XF86AudioRaiseVolume

# Decrease volume
"sh $HOME/bin/sound.sh down"  
    m:0x0 + c:122
    XF86AudioLowerVolume

# Toggle mute
"sh $HOME/bin/sound.sh mute"  
    m:0x0 + c:121
    XF86AudioMute

"sh $HOME/bin/brightness.sh inc"  
    m:0x0 + c:233
    XF86MonBrightnessUp

"sh $HOME/bin/brightness.sh dec"  
    m:0x0 + c:232
    XF86MonBrightnessDown

Now we have all the pieces, we only need to launch the xbindkeys command at every boot.

To do this, add xbindkeys & to your ~/.xinitrc.

See my own xinitrc on github.

End

I hope it was a handy post for you Lenovo users.

Any other tip you want to share? Comment and I will add them.

comments powered by Disqus