Linux on the Dell XPS 15 Touch (9570)

Mar 03 2019

UPDATED: 18 March 2019 - External display adapters that actually work with this model (and Arch Linux) added.

For various reasons, I found that I had a need to upgrade Windbringer's hardware very recently.  This might be the first time that a catastrophic failure of some kind was not involved, so it's kind of a weird feeling to have two laptops side by side, one in process and one to do research as snags cropped up.  This time around I bought a Dell XPS 15 Touch (9570) - I was expecting things to be substantially the same, but this did not seem to be the case.  Some things that I found myself ignoring because I had no use for them aren't in this newer model, and some things have changed as technology has advanced rather a lot in the last five years.

As before, first I'll post the hardware specs, and then follow up with everything I had to tinker with to get working as well as how I went about it.  As usual, I went with 64-bit Arch Linux (2019.02 installation build).

Kernel: 4.20.12-arch1-1-ARCH #1 SMP PREEMPT Sat Feb 23 15:11:34 UTC 2019 x86_64 GNU/Linux

Hardware:

  • Intel i9-8950HK CPU
    • 2MB cache
    • 4.8 GHz
    • 6 cores, 2 threads each
  • 32GB DDR4-2666MHz RAM (maxed out)
  • Video: Intel Corporation UHD Graphics 630 (Mobile) (i915, basically)
  • Video: NVIDIA® GeForce® GTX 1050Ti with 4GB GDDR5 vRAM (via Optimus)
  • Audio: Intel Corporation Cannon Lake PCH cAVS (this is basically the i915 audio chipset, nothing to write home about)
    • SATA controller: Intel Corporation Cannon Lake Mobile PCH SATA AHCI Controller
  • 2TB PCIe SSD
  • 15.6" HD display @ 3840 x 2160 touchscreen
  • Killer 1535 802.11ac 2x2 WiFi and Bluetooth 4.2
    • The output of `lspci` says this is a Qualcomm Atheros QCA6174 802.11ac Wireless Network Adapter.
  • 97WHr power cell
  • 130W PSU (the same one as my last XPS 15)
  • Built-in video camera: Microdia (the default `uvcvideo.ko` picks this up automatically)
  • SD card reader
  • USB 3.1 gen 1
  • Laptop security cable slot
  • HDMI 2.0
  • Thunderbolt 3
  • Fingerprint reader inside the power button.
    • I have no idea how to interact with this.

Before booting from a flash drive with the Arch Linux installer on it, I jumped into the system settings by tapping the F2 key a few times a second (don't just hold it down) after hitting the power button.  In the Dell system options I made a few minor changes to make life easier later on:

  • System Configuration -> SATA Operation -> AHCI
  • Secure Boot menu -> Secure Boot -> disabled (so that I don't have to muck around with signing kernels)
  • Power Management menu -> Primary Battery Charge Configuration -> AC plugged in most of the time (because I mostly use my laptop at home)
  • POST Behavior menu -> Extend BIOS POST time -> five seconds (so I have time to hit F2, F12, or whatever)
  • POST Behavior menu -> Full Screen Logo -> disabled
  • Virtualization Support menu -> Virtualization -> enabled (I use VirtualBox from time to time)
  • Virtualization Support menu -> VT for Direct I/O -> enabled

To make the system console font (not the X environment's typefaces) bigger, I installed the terminus-font package and ran the command setfont ter-132b to get bigger text.  To make this a permanent feature I created the file /etc/vconsole.conf with the following contents:

FONT=ter-132b
FONT_MAP=8859-2

One thing that I discovered right up front is that the SSD doesn't appear as /dev/sda or /dev/sdb (like it did on the earlier model XPS 15).  Instead it shows up as /dev/nvme0, but that's not actually the disk device; I think that's just the PCIe interface.  The actual disk device that you interact with using fdisk is /dev/nvme0n1, so my partitions are actually called /dev/nvme0n1p1 and /dev/nvme0n1p2.

Before moving on, make a note of the GUID of your physical root partition for setting up the boot loader later.  Let's say it's 8468e49d-29b7-4353-8379-59b7e7996add.

The biggest jump I made here was to ignore BIOS backwards-compatibility entirely and go whole-hog on using UEFI (Unified Extensible Firmware Interface) to join the twenty-first century.  This wound up being a remarkably easy thing to get going.  When I partitioned the SSD, after blowing away all of the factory stuff I created a 512 megabyte /boot partition of type FE00 (EFI System) and formatted it as VFAT (one of the few filesystems the UEFI spec supports (they're all old-time DOS file systems)) and then a root partition that filled up the rest of the drive of type 82 (Linux filesystem).  The root partition was set up with the usual Arch dm-crypt procedure.  I installed a basic Arch Linux system and then used systemd's built-in UEFI boot loader (called systemd-boot) to make everything bootable.  Here's how I did it:

  • bootctl install
  • cd /boot/loader
  • vim loader.conf
timeout 5
console-mode 0
default arch
  • cd entries
  • vim arch.conf
title Arch Linux
linux /vmlinuz-linux
initrd /intel-ucode.img
initrd /initramfs-linux.img
options root=/dev/mapper/root cryptdevice=UUID=8468e49d-29b7-4353-8379-59b7e7996add:root:allow-discards rw mem_sleep_default=deep acpi_rev_override=1
  • vim fallback.conf
title Arch Linux Fallback
linux /vmlinuz-linux
initrd /intel-ucode.img
initrd /initramfs-linux-fallback.img
options root=/dev/mapper/root cryptdevice=UUID=8468e49d-29b7-4353-8379-59b7e7996add:root rw
  • An easy way of getting the GUID into those two config files is to use this command inside of vim so you don't have to retype them:
    • <hit esc>:r !blkid -s UUID -o value /dev/nvme0n1p2

After doing this, your system should boot normally; you don't need any other boot loader or software for the system to come up.  As far as the UEFI systemware is concerned, the Linux kernel is an EFI application so it runs it like any other.

I followed the nVidia Optimus instructions in the Arch wiki.  When installing Xorg on this model, do NOT install the xf86-video-intel package.  Those Xorg drivers will not work.  I installed bumblebee, bbswitch, and the official nVidia drivers, and then made the following configuration changes to /etc/bumblebee/bumblebee.conf:

  • TurnCardOffAtExit=true
  • Bridge=auto
  • PMMethod=none
    • Because TLP is handling this.

I also created a config file /etc/tmpfiles.d/nvidia_pm.conf with the following contents to fully enable power management for the nVidia chip:

w /sys/bus/pci/devices/0000:01:00.0/power/control - - - - auto

I got the value "0000:01:00.0" in the previous file by interrogating the integrated devices in the laptop, like this: lspci | grep -i nvidia | awk '{print $1}'

I'm using TLP for power management because I'm too old to screw around with all those config files.  I did have to do one thing, though, which is tell TLP to not manage power for the nVidia chip, because Bumblebee is going to do that.  I edited the file /etc/default/tlp and made the following change (where 01:00.0 is the PCI bus value above):

RUNTIME_PM_BLACKLIST="01:00.0"

In the /etc/systemd/logind.conf file, I uncommented the HandleLidSwitch line and set it to "ignore" because I want my desktop software to do that for me.

Due to the fact that my new laptop has only a solid-state drive for storage, I enabled periodic TRIMming of deleted data to keep the drive healthy.  If you look in the /boot/loader/entries/arch.conf file earlier in this post, you will see that the kernel is being passed the option :allow-discards.  This turns on TRIM support.  Actually enabling this functionality required two further commands:

  • systemctl enable fstrim.service
  • systemctl enable fstrim.timer

Last and certainly not least, migrating my home directory onto the new laptop.  The fastest and most reliable way to do this was to dig out an Ethernet switch and two USB-to-Ethernet adapters.  I plugged the two systems together into a little ad-hoc network on my workbench.  I don't do this very often, so in case I forget again (or if someone needs this in the future), here are the commands I ran on both the old and new laptops:

  • ifconfig | grep enp | awk '{print $1}'
  • ifconfig <interface name> 10.0.0.[2, 3] netmask 255.255.255.0 up
    • Give the network interface the IP address 10.0.0.2 or 10.0.0.3.
  • route add -net 10.0.0.0 netmask 255.255.255.0 dev <interface name>
    • Set a route for the network 10.0.0.0/255.255.255.0 that points to the USB-to-Ethernet interface.
  • ping -c5 10.0.0.[2, 3]
    • If you're on 10.0.0.2, try to ping 10.0.0.3 and vice-versa.

The command to copy everything from the old system onto the new one: rsync -avz --progress drwho/ drwho@10.0.0.3:/home/drwho/

Total time: About 26 hours (and you wonder why I do so much work with personal search engines!)

I fought for a week or two trying to get external displays to work with this particular unit.  As it turns out, adapters (and/or displays) you want to use have to be Active in construction, which is to say that they cannot merely be pin-to-pin converter cables, there has to be circuitry on-board doing signal processing.  After some consternation I remembered that I had an HDMI-to-VGA converter (Moread male HDMI to female VGA) in my field kit for presenting on the road.  I plugged it in - HDMI-to-VGA adapter to VGA cable to external display, and it came right up without needing to reconfigure X (modulo needing to turn up the brightness and contrast a bit).  I've also just tested an Itanda USB-C to mini-Displayport adapter purchased from Amazon, and much to my surprise and delight it works too, also with no reconfiguration.