Dual-Booting Arch Linux on Lenovo X1 Carbon 3rd gen «

Code: , , , , , , , ,

I decided to replace my mid-2011 Macbook Air 3,2 with a non-Apple machine, but every laptop I looked at was unsuitable. Most were overpriced, with a big and clunky design. The Lenovo X1 Carbon was promising, but the 2nd generation had a keyboard that was just too weird (and the function keys changing modes means you can’t touch-type them anymore). Standard qwerty is bad, but it’s the devil I know.

That was a year ago. In January 2015 Lenovo released a third generation of the X1 Carbon with some slightly improved specs and a normal keyboard, so I picked one up. I decided to switch from Ubuntu because I’ve felt out-of-touch with how it works under the covers and I’ve been curious about Arch Linux. This post is my notes on setting that up.

2016-04-07: A year and three weeks after I started using this laptop (I know precisely because that put the laptop juuuust out of warranty), without warning or accident, the display stopped working. Lenovo’s expensive repair service estimated 6 businesses days for repair but the repair took over 5 weeks. If you might purchase a Lenovo laptop (perhaps the recent X1 Carbon 4th gen), I suggest you consider whether randomly losing hundreds of dollars and access to your laptop for 5 weeks would inconvenience you. 2016-05-16: …and by “5 weeks” I mean “9 weeks”. When Lenovo sent my laptop back with a new motherboard, it was one model down with slower processor, half the RAM, etc. It took another several weeks of dealing with their incompetent bureaucracy before they replaced it. 2016-12-18: Well, shit, the display on the replacement has started flickering.

BIOS Settings

The out-of-the box settings were decent, but I made a few tweaks.


The laptop shipped with Windows 8.1 Standard installed. I wanted to keep it around for a few video games that don’t run on Linux, which meant resizing down its partition, removing the recovery partition, and removing a mysterious undeletable 7 GB “OEM partition”. The next paragraph is a rant and can be safely ignored.

Windows 8.1 is flippers-on-dry-land unusably bad. I have no idea how this shipped. I counted four GUI toolkit styles, inconsistent navigation, missing help files, privacy-invasive defaults, and settings broken up into several different screens in different programs that all look and work differently. Programs appeared and disappeared with little or no reason. Random DLL crashes on every boot. And even after tidying the many places it wastes disk space it needs 25 GB before any programs are installed. I can’t understand how people put up with this for daily use and spent an evening overwhelming frustrated after a couple hours of trial use. That the most common operating system looks and acts this way is a failure for my profession.

Removing the Windows recovery partition was easy. One of Windows’ several disk management programs slowly copied it to a 16 GB and removed the partition.

None of Windows disk management programs could explain or delete the “OEM partition”. This partition exists for the Intel Rapid Start feature, which (despite the name) exists to save battery life. IRS waits until the computer has been asleep for a while, copies RAM into this partition, and halts the computer. When the computer is started it takes a few seconds to restore RAM and the computer is usable normally. If this sounds an awful lot like the Windows/Linux “hibernate” feature, that’s because it’s the exact same thing implemented in the BIOS instead of the OS. And it saves your RAM unencrypted, so a thief can extract passwords, encryption keys, etc.

Even after turning off this misfeature in the BIOS, the Windows tools refuse to delete the partition, but if you can figure out how to start an admin console diskpart can remove the partition. I also jumped through some hoops to turn off swapping (the pagefile.sys) and hibernation (hiber.sys) and reclaim some disk space, but it’s too tedious to recount.

The Windows disk tools can enlarge an NTFS storage partition but could barely shrink it… it claimed the smallest the 230 GB partition could be reduced to was 111 GB.

But I had my Arch Linux bootable USB key in hand and was off to Linux to get this computer set up. A quick setfont sun12x22 made the terminal a lot more readable on the HiDPI 2560×1440 screen.

The ntfsresize program quickly prepared the the NTFS partition for resizing. (It would be better named “ntfscompact”, because it compacts the drive content in preparation for resizing; it does not change parition size on its own.) I used ntfsresize -i /dev/sda4 to examine it, ntfsresize -nv -b -s 40G /dev/sda4 to test, and the same command without the -n to do the job in a few seconds.

After shrinking it, I used gdisk to “resize” it by deleting the partition and creating a new partition that starts at the same sector, has the same 0700 “Microsoft basic data” partition type, but is only 40 GB large. I used the “i” command to print info about the partition, snapped a photo with my camera, and used that to replace the “Partition unique GUID”. I don’t know if Windows would care if it changed, but it was so easy to carry over I didn’t want to risk it.

Finally I added a partition filling the rest of the disk space with the type 8300 for Linux, wrote the table, and rebooted to see Windows still working (phew).

Linux Partitioning

I see a lot of client data and security keys as a consultant. Last year I worked on an app that did essential financial planning for a multi-billion dollar multinational company. If my laptop is lost or stolen, I don’t want that data (or my own personal data) easily readable.

Using the dm-crypt guides and Pavel Kogan’s notes on encrypting /boot, I set up full-disk encryption. GRUB is the only part of the Linux system unencrypted, which would be much more of a pain in the ass to compromise than an unencrypted /boot partition in the vanishingly-unlikely case that someone wanted to break the encryption. This is a nice little improvement for a little extra work, but I’m more concerned with protecting against opportunistic thieves than evil maids.

One major difference is that I didn’t mess around with LVM. I only want a single root partition filling my whole drive with /boot encrypted inside. I won’t be resizing or rearranging partitions, so there’s no reason to take on extra complexity for that unused optoin. With that in mind, and the Arch guides to device encryption, system configuration, and encrypting an entire system explaining all the details, here’s my command log:

# encrypt and format the partion
cryptsetup -c aes-xts-plain64 -s 512 luksFormat /dev/sda5
cryptsetup luksDump /dev/sda5
cryptsetup luksOpen /dev/sda5 root
mkfs.ext4 /dev/mapper/root
mount /dev/mapper/root /mnt

My hard drive setup is done until it’s time to finish configuring grub for the encrypted volume, so it’s on to the installation guide:

Bootstrapping Arch

Following the guide was easy:

wifi-menu # took a few tries to see my network
vi /etc/pacman.d/mirrorlist # commented everything out, uncommented a few US mirrors
pacstrap /mnt base
genfstab -L -p /mnt >> /mnt/etc/fstab
arch-chroot /mnt
echo [hostname] > /etc/hostname
ln -sf /usr/share/zoneinfo/US/Central /etc/localtime
vi /etc/locale.gen # search for _US, uncomment
echo en_US.UTF-8 > /etc/locale.conf
echo FONT=sun12x22 > /etc/vconsole.conf
cp /usr/lib/systemd/system/systemd-vconsole-setup.service /etc/systemd/system/systemd-vconsole-setup.service

I did have to edit /etc/fstab to change relatime to noatime on root and add the EFI and Windows partitions:

/dev/mapper/root / ext4 rw,noatime,data=ordered 0 1
efivars /sys/firmware/efi/efivars efivars defaults 0 0
/dev/sda2 /boot/efi vfat rw
/dev/disk/by-label/Windows8_OS /opt/Windows8_OS ntfs rw,noauto

I also had to edit that copied system-dvconsole-setup.service file to add After=systemd-udev-settle.service and Wants=systemd-udev-settle.service under the [Unit] heading to set the font after the graphics driver was loaded, as described here.

As prompted by Kogan’s encryption guide, I created the encryption keyfile and added it to LUKS:

dd bs=512 count=4 if=/dev/urandom of=/crypto_keyfile.bin
cryptsetup luksAddKey /dev/sda5 /crypto_keyfile.bin
mkinitcpio -p linux
pacman -S grub efibootmgr
vi /etc/mkinitcpio.conf
vi /etc/default/grub

With that first vi I added “encrypt” to HOOKS and “/crypto_keyfile.bin” to FILES in mkinitcpio.conf. With the second I added grub to add:


before I run this (which needs to run every time grub’s config is tweaked):

grub-mkconfig -o /boot/grub/grub.cfg
grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=grub_uefi --recheck

Next, time to install some basic networking tools so I can install the rest of the system from inside itself rather than the bootable usb:

pacman -Syyu
pacman -S iw dialog net-tools pkgfile wpa_supplicant
pkgfile --update

Figuring out which packages I needed involved a lot of booting from the usb and running the following commands.

cryptsetup luksOpen /dev/sda5 root
mount /dev/mapper/root /mnt
arch-chroot /mnt

Then I exited the arch-chroot and ran umount -R /mnt to see everything cleanly unmount.

Installing Arch

It’s finally time to configure wifi (replacing the network ssid and password in brackets) and connect:

# I had to bring the network up manually, first:
wpa_supplicant -B -D nl80211,wext -i wlp4s0 <(wpa_passphrase <essid> <passphrase>)
dhcpcd wlp4s0
# then save it
wifi-menu # saved as wlp4s0-<essid>
netctl enable wlp4s0-<essid>

I lost a lot of time trying to get netctl to work reliably with wpa_supplicant. Sometimes it just failed to work after a reboot. Disabling netctl in favor of NetworkManager (whether through nm-applet or nmcli) was a big win.

Next I need to shave a different herd of yaks. I want to use etckeeper to track /etc (this turned out to be absolutely vital as I struggled with netctl). Which means I need to build and install it from the Arch User Repository, which I’d like to do with aura, which means I need to install enough tools to build and install that, which means I need to create a user account (for makepkg to run)…

# add a user:
useradd pushcx
passwd pushcx
visudo # to append "pushcx ALL=(ALL) ALL"
# log out, log in as pushcx
# install aura:
curl https://aur.archlinux.org/packages/au/aura-bin/aura-bin.tar.gz -O
tar -xvf aura-bin.tar.gz
makepkg -s
sudo pacman -U aura-bin-
# install etckeeper:
sudo aura -Ai etckeeper
sudo aura -Ap etckeeper
sudo aura -Ax etckeeper
# configure etckeeper:
sudo etckeeper init
sudo git config --global user.email "root@hostname"
sudo git config --global user.name "root"
sudo git commit -m "initial commit"
sudo git gc # saved 5m

Phew, not too bad a shave, and I’m starting to see the Arch philosophy at work. This feels a lot like Slackware with some build automation. I used Slackware for about six years until I realized I wasn’t learning anything new. Lately I’ve felt out of touch with how my Linux install works; I hope Arch is the right level of automation and configuration.

(Speaking of philosophy, even after reading the justification I don’t understand how Arch settled on systemd. It seems the antithesis of the Unix Way and the Arch Way. I’m glad to be learning it as the majority of distros are moving to it, but it’s a beast.)

Digging into the general recommendations page showcases what first caught my attention about Arch: comprehensive, decently-written documentation about all aspects of the system. I’ve already been using Arch’s wiki for tips on understanding and maintaining my Ubuntu system for a year or so.

Meanwhile, I’ll add some basic packages, get into configuring the GUI, and test all the hardware drivers.

GUI Configuration

timedatectl set-ntp true
# console essentials:
pacman -S openssh tree tmux vim
# x essentials:
pacman -S xorg-server xorg-xinit lightdm \
lightdm-gtk3-greeter awesome vicious xterm \
urxvt-unicode notification-daemon ttf-freefont \
ttf-dejavu xorg-xmodmap xorg-xrdb gnome-keyring
# drivers:
pacman -S libva-intel-driver xf86-video-intel xf86-input-evdev xf86-input-synaptics

To configure lightdm, I created a ~/.xprofile:

eval $(/usr/bin/gnome-keyring-daemon --start --components=pkcs11,secrets,ssh)
xrdb -merge $HOME/.Xdefaults &
gnome-settings-daemon &
nm-applet &

And I had startx‘s startup script ~/.xinitrc call that:

[ -f ~/.xprofile ] && source ~/.xprofile
exec awesome

And added a ~/.Xresources for the HiDPI display:

xterm*utf8: 1
Xft.dpi: 180
Xft.autohint: 0
Xft.lcdfilter: lcddefault
Xft.hintstyle: hintfull
Xft.hinting: 1
Xft.antialias: 1
Xft.rgba: rgb

I configured /etc/lightdm/lightdm-gtk-greeter.conf similarly:


Starting X and poking around my virtual terminals, Xorg was on F1, F2-F6 were more consoles, and F7 displayed a horizontally flickering cursor. After seeing that flicker, switching to Xorg or the text terminals displayed the same horizontal flickering; it looked like it was trying to repeatedly draw the screen at several different horizontal offsets that moved in and out of phase. This seems to be a bug in the intel video driver I’ll need to report; it appears fairly regularly as I switch between console and video modes.

2015-03-15: This was fixed in the latest version of the xf86-video-intel driver. Thanks to Jeremy Fleischman for the heads up.


I installed the laptop mode tools and configured powersaving. After running a laptop with a 3.5 year old battery, I’m really delighted and impressed to see 6-8 hour battery times when I nudge the LCD brightness down a little (in X or by editing /sys/class/backlight/intel_backlight/brightness) and even more if I turn off the wifi.

pacman -S laptop-mode-tools acpi acpid ethtool wireless_tools
systemctl enable laptop-mode

/etc/laptop-mode/laptop-mode.conf only needed one or two tweaks, like LM_BATT_MAX_LOST_WORK_SECONDS=60. The acpi command line tool is handy for watching battery from the console (I was buddy breathing my AC adaptor during the install).


Following the wiki instructions:

pacman -S bluez bluez-utils gnome-bluetooth
hciconfig hci0 up
[bluetooth]# devices
[bluetooth]# scan on
# ... wait a minute ...
[bluetooth]# scan off
[bluetooth]# agent on
[bluetooth]# pair F0<tab>
[bluetooth]# trust F0<tab>
[bluetooth]# connect F0<tab>

And to bring bluetooth online automatically after restarts, add /etc/udev/rules.d/10-local.rules:

# Set bluetooth power up
ACTION=="add", KERNEL=="hci0", RUN+="/usr/bin/hciconfig hci0 up"

This works fine, but I also did aura -A blueman for a nice X applet.

In Conclusion

Hope this helps if you’re setting up Linux on an X1 Carbon or just curious about what the steps of setting up Arch Linux look like. As expected, Arch is a whole lot of fiddly little configuration steps. They gave me the excuse I wanted to see current Linux software config and tinker, but it’s quite time-consuming.

2015-02-12: I’ve started a page on the Arch wiki about the X1 Carbon (3g). It contains more information than this about setting it up, including some known bug.


  1. Thanks for posting this, I’m about to order this laptop. May use Antergos instead.

  2. Thanks for the detailed post! I am also running arch on my X1 Carbon Gen 3, and am seeing this display driver bug intermittently. I’m not sure that it only happens when switching between console and video modes (left my laptop in X last night, and woke up to the bug this morning). Do you know if a bug has been filed yet for this issue?


  3. For those lurking, the display bug has been fixed in the latest version of the xf86-video-intel driver.

  4. Hi, I’m experiencing the exactly same display bug you had, using the latest intel driver. Did you find a way solve the problem?

  5. Found your writings thanks to the Arch wiki on that model. Just popping to STRONGLY agree on the Philosophy vs systemd issue – for as much as we will have to do with systemd, there is no doubt about it, the nostalgic me suffers greatly from the times of a single, central config file that defined the whole of your install – and was the sexy thing which had me jump ship from… Slackware!

    Arch still has tremendous arguments in its favour, and that includes the very interesting learning curve, but I’d hope the dev team somehow, one day, achieve to hack systemd back into a single file, these-are-all-my-settings way.

    Thanks for this post.

  6. regarding Lenovo service – I also had a display issue with this laptop, about a month past default warranty. Lenovo wanted ~600 to fix it, but ~200 to extend the warranty.

    Catch of course was that I had to wait 4 weeks to send it in, at which time the repair only took about 5-6 days. Luckily in my case the issue affected part of the display so the laptop was “usable” over the 4 weeks.

    This was my second repair with lenovo, and in both cases my turnaround time was just shy of a week – not sure why yours took 5 weeks.

    Anyway, thanks for the guide! My Win 10 install is broken, so I’m about to give Arch / Win dual a shot.

  7. Thanks for providing all of this great information in such clear and concise prose. Cheers.

Leave a Reply

Your email address will not be published.