Dual-Booting Arch Linux on Lenovo X1 Carbon 3rd gen
« Isolating Polymorphism
» Hiring Apprentices
Code: Arch Linux, configuration, hardware, Lenovo, Linux, Windows, Windows 8.1, X1 Carbon, yak shave
Comments Off on Dual-Booting Arch Linux on Lenovo X1 Carbon 3rd gen
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.
- Config
- Wake on LAN: Disabled. I don’t use it.
- USB/Charge in Battery Mode: Enabled. I want to be able to charge my phone in my bag.
- Power/Intel Rapid Start: Disabled. Insecure hibernation. See partitioning below.
- Intel(R) AMT/Intel (R) AMT Control: Disabled. I do not have an enterprise IT department accessing my laptop.
- Security
- Security Chip/Security Chip: Disabled. A chip to prove to copyright owners that your computer is secure to them against you.
- Anti-Theft/Computrace: Disabled. A kill switch owned by someone else.
- Secure boot/Secure boot: Disabled while installing Linux, re-enabled after.
- Startup
- Option key Display: Disabled. Just looks nicer.
Partitioning
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
locale-gen
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
passwd
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:
GRUB_ENABLE_CRYPTODISK=y
GRUB_CMDLINE_LINUX="cryptdevice=/dev/sda5:root"
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.
wifi-menu
cryptsetup luksOpen /dev/sda5 root
mount /dev/mapper/root /mnt
arch-chroot /mnt
Then I exit
ed 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
dhcpcd wlp4s0
# then save it
wifi-menu # saved as wlp4s0-
netctl enable wlp4s0-
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-1.3.0.2-1-x86_75.pkg.tar.xz
# install etckeeper:
cd
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
:
#!/bin/sh
eval $(/usr/bin/gnome-keyring-daemon --start --components=pkcs11,secrets,ssh)
export SSH_AUTH_SOCK
xrdb -merge $HOME/.Xdefaults &
gnome-settings-daemon &
nm-applet &
And I had startx
‘s startup script ~/.xinitrc
call that:
#!/bin/sh
[ -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:
[greeter]
xft-antialias=true
xft-dpi=180
xft-hintstyle=hintfull
xft-rgba=rgb
hide-user-image=true
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.
Powersaving
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).
Bluetooth
Following the wiki instructions:
pacman -S bluez bluez-utils gnome-bluetooth
hciconfig hci0 up
bluetoothctl
[bluetooth]# devices
[bluetooth]# scan on
# ... wait a minute ...
[bluetooth]# scan off
[bluetooth]# agent on
[bluetooth]# pair F0
[bluetooth]# trust F0
[bluetooth]# connect F0
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.