Linux on ThinkPad X1 Carbon 7th Gen

I recently upgraded my 3rd Gen X1 Carbon to a 7th Gen model. I decided to document my experience in the hopes of it being useful to someone in the future. The Arch wiki has a good starting reference. I'll also try to keep the Gentoo wiki updated.

Migrating

I used rsync to transfer my root filesystem to an external drive. After booting the new machine with a minimal installation image, I partitioned, formatted and mounted volumes, and used rsync to transfer the file system from the external drive. I considered testing my recovery strategy by restoring from backup, but I assumed there would be a period of working on both machines and I wanted to ensure changed files on old could quickly be copied to new. rsync is better for that than tar.

Another advantage of rsync is that I could use the old machine to install packages. The Ethernet adapter I had for the X1C3 isn't compatible with the X1C7, and although it wouldn't have been difficult to do, I was too lazy to fiddle with wpa_supplicant in the minimal installation shell. So I installed efibootmgr and a few other tools on the old machine, and used rsync to copy them over to the new machine. qpkg would have also worked, but I was striving for minimum friction and maximum lazy.

I'm running kernel 5.2.11 and this is my working kernel config. I changed my -march flag in make.conf from broadwell to skylake. I avoid using native because I want to be able to copy the root filesystem to another machine without worrying too much about CPU compatibility.

UEFI and Syslinux

I disabled native UEFI booting on my X1C3 out of pure laziness because I migrated an installation over from a previous machine that used MBR. Well, the X1C7 doesn't support legacy USB emulation which is necessary to make the keyboard work after booting a minimal installation image in legacy boot mode. I couldn't find any mention of this anywhere, probably because I'm in the tiny minority of people still booting from a MBR.

I prefer to use Syslinux for a bootloader because Grub2 is far too complex for my liking. (Yes, I know I don't technically need a bootloader with UEFI but I want one anyway.) I already had a Syslinux installation on my old system so I followed the Gentoo handbook and wiki to convert it to UEFI. Unfortunately, the recommended configuraiton didn't work for me. Renaming the syslinux directory to boot and syslinux.efi to bootx64.efi seemed to fix it.

I'm mounting the EFI partition to /boot/efi. Here's what /boot looks like for me:

$ ls -R /boot
/boot:
total 16K
lrwxrwxrwx 1 root root   1 Aug 31 16:20 boot -> .
drwx------ 3 root root 16K Dec 31  1969 efi

/boot/efi: total 24M
drwx------ 3 root root 2.0K Aug 31 17:29 EFI
-rwx------ 1 root root 8.1M Sep  1 18:01 initramfs-genkernel-x86_64-5.2.11-gentoo
-rwx------ 1 root root  11M Sep  7 22:44 kernel-5.2.11-gentoo
-rwx------ 1 root root 4.9M Sep  7 22:44 System.map-5.2.11-gentoo

/boot/efi/EFI: total 2.0K
drwx------ 2 root root 2.0K Sep  7 19:34 boot

/boot/efi/EFI/boot: total 588K
-rwx------ 1 root root 173K Aug 31 23:20 bootx64.efi
-rwx------ 1 root root 131K Aug 31 23:20 ldlinux.e64
-rwx------ 1 root root 192K Aug 31 23:20 libcom32.c32
-rwx------ 1 root root  24K Aug 31 23:20 libutil.c32
-rwx------ 1 root root  32K Aug 31 23:20 menu.c32
-rwx------ 1 root root  259 Sep  7 19:34 syslinux.cfg
-rwx------ 1 root root  32K Aug 31 23:20 vesamenu.c32

Storage

I had to enable NVMe support to allow the kernel to find the hard drive. The X1C3 used a traditional SSD so the option wasn't previously needed.

Device Drivers --->
  NVME Support --->
    <*> NVM Express block device

Touchpad

I had a lot of trouble making the touchpad work. Booting Ubuntu 18.04 from USB media proved there are working Linux drivers, however, I couldn't find any documentation for the complete set of drivers needed. Through trial, error, and lots of profanity I worked out these options:

Processor type and features --->
  [*] Intel Low Power Subsystem Support
Device Drivers --->
  Input device support --->
    [*] Mice --->
      <*> Synaptics I2C Touchpad support
    <*> Synaptics RMI4 bus support
    <*>   RMI4 I2C Support
    <*>   RMI4 SMB Support
    [*]   RMI4 Function 03 (PS2 Guest)
    [*]   RMI4 Function 11 (2D pointing)
    [*]   RMI4 Function 30 (GPIO LED)
    [*]   RMI4 Function 34 (Device reflash)
    [*]   RMI4 Function 54 (Analog diagnostics)
    -*-   RMI4 Function 55 (Sensor tuning)
  I2C Support --->
    -*- I2C support
       I2C Hardware Bus support --->
         <*> Intel 82801 (ICH/PCH)
         <*> SMBus Control Method Interface
         <*> Synopsys DesignWare Platform
         <*> Synopsys DesignWare PCI
  -*- Pin controllers --->
    <*> Intel Canon Lake PCH pinctrl and GPIO driver
  Multifunction device drivers --->
    <*> Intel Low Power Subsystem support in ACPI mode
    <*> Intel Low Power Subsystem support in PCI mode
  HID support
    -*- HID support
    <*> Generic HID driver
        Special HID drivers --->
          <*> Lenovo / ThinkPad devices
          <*> HID Multitouch panels
  [*] DMA Engine support --->
    <*> Intel integrated DMA 64-bit support
    -*- Synopsys DesignWare AHB DMA PCI driver
  [*] X86 Platform Specific Device Drivers --->
    <*> ThinkPad ACPI Laptop Extras
    <*> WMI
    <*>   WMI embedded Binary MOF driver

I did not need the psmouse.synaptics_intertouch command line argument as some other posts suggested. When it's working successfully you should see these lines in the dmesg output:

[    2.270832] idma64 idma64.0: Found Intel integrated DMA 64-bit
[    2.315611] idma64 idma64.1: Found Intel integrated DMA 64-bit
[    2.963063] input: SYNA8004:00 06CB:CD8B Touchpad as /devices/pci0000:00/0000:00:15.1/i2c_designware.1/i2c-8/i2c-SYNA8004:00/0018:06CB:CD8B.0001/input/input7
[    2.963173] hid-multitouch 0018:06CB:CD8B.0001: input,hidraw0: I2C HID v1.00 Mouse [SYNA8004:00 06CB:CD8B] on i2c-SYNA8004:00

The absence of the idma64 lines helped me figure out the need to enable that option. LPSS, pinctrl, and WMI were guesses from comparing my kernel config with the Ubuntu config. Ubuntu lists the touchpad device as SYNA8005 which is clearly different from the dmesg output.

Capabilities

One disapponting gotcha I did encounter was the KDE screen locker not accepting my password. It turns out (on Gentoo systems at least) the unix_chkpwd utility makes use of capabilities to access the shadow file. Those capabilities weren't transferred by rsync but the solution was simple enough:

$ setcap cap_dac_override+ep /sbin/unix_chkpwd

I was concerned other files had capabilities that weren't transferred. So on the old machine I ran:

$ find / -type f -exec getcap {} \; 2>/dev/null

And I did end up needing to set more capabilities:

$ setcap cap_setfcap+i /sbin/setcap
$ setcap cap_sys_resource+ep /usr/lib64/libexec/kf5/start_kdeinit
$ setcap cap_net_bind_service,cap_net_admin+ep /usr/lib64/gstreamer-1.0/gst-ptp-helper
$ setcap cap_net_admin+ep /usr/libexec/qemu-bridge-helper
$ setcap cap_dac_read_search,cap_net_admin,cap_net_raw+ep /usr/bin/dumpcap
$ setcap cap_net_raw+ep /bin/ping
$ setcap cap_net_raw+ep /bin/arping

Ultimately, re-emerging everything is probably a simpler way to ensure things are installed properly.