Linux on the ThinkPad X1 Carbon

Allin Cottrell <cottrell at wfu.edu>, August 15, 2013 (slightly updated 2014-06-04)

Wake Forest faculty and students are issued Lenovo ThinkPads. The model I have currently is the X1 Carbon. And a nice machine it is too.

Specs | Linux summary | Installation | Wrinkles | False start | Details

Specifications

I have the model 34483Q0 with 8GB RAM, 256GB SDD, CORE i7 vPro, and Intel graphics. It comes with Windows 8 installed. See here and particularly here for more info.

Linux summary

Basically, modern Linux "just works" on this machine -- once you get it installed! As of this writing I'm using kernel 3.10.7 and Xorg server 1.14.2. The Intel Ivybridge graphics are supported nicely, with direct rendering enabled. Regarding the main kernel modules in use, audio is supported by snd-hda-intel, ethernet (via USB adapter) by usbnet, wifi by iwlwifi, built-in webcam by uvcvideo, video by i915. Care to see a screen shot?

Installation

I don't use a Linux "distro" -- I have a system of my own that I have fine-tuned over the years. When I get a new ThinkPad, I back up the old system to a USB memory stick in the form of gzipped tarfiles. After setting up the new hard drive, I copy the system over and tweak it as needed for the new machine.

My installation followed these steps:

  1. Turn off "secure boot" in the UEFI BIOS setup (pump F1 on start-up to get in).
  2. Boot Windows 8 and shrink the Windows C drive (using Control Panel, Administrative Tools, Computer Management, Disk Management). In contrast to my experience a couple of years ago attempting resizing under Windows 7, this was unproblematic.
  3. Boot from a Linux SystemRescue USB stick (pump F12 on start-up to get this option). The current SystemRescue image is EFI-enabled, so it's not necessary to enable "legacy BIOS" support. Create a Linux partition using gdisk. (Note that the traditional fdisk is no use with a GPT drive setup.) Make an ext4 filesystem using mkfs.ext4. Decompress my system files from a second USB stick to the new Linux partition.
  4. Boot Windows 8 to check the resized NTFS partition. OK.
  5. Reboot with SystemRescue and rejig the ESP to make refind the active boot manager. Also install elilo with an EFI-enabled Linux kernel. This step was not totally a piece of cake -- see Wrinkles below, also Details.

The machine came with the SSD carved into four partitions: "Microsoft Reserved"; "Windows Recovery"; the EFI System Partition (ESP); and the Windows C drive. After shrinking the latter and adding a Linux partition, my hard drive looks like this (via gdisk):

Disk /dev/sda: 500118192 sectors, 238.5 GiB
Logical sector size: 512 bytes
Disk identifier (GUID): [...]
Partition table holds up to 128 entries
First usable sector is 34, last usable sector is 500118158
Partitions will be aligned on 2-sector boundaries
Total free space is 2582494 sectors (1.2 GiB)

Number  Start (sector)    End (sector)  Size       Code  Name
   1              34          262177   128.0 MiB   0C01  
   2         2844672         3459071   300.0 MiB   2700  
   3         3459072         3663871   100.0 MiB   EF00  
   4         3663872       186771455   87.3 GiB    0700  
   5       186771456       500118158   149.4 GiB   8300  Linux filesystem

Wrinkles

This was the first time I'd messed with a UEFI/GPT machine. In place of the trusty lilo that I've used in the past, dual-booting (along with Windows 8) is handled via the combination of refind and elilo.

In principle, elilo should not be required; it should be enough to build a Linux kernel with EFI stub enabled (so it acts like an .efi file), and have refind launch it. But this doesn't work on the X1 Carbon. Maybe at some point a BIOS update will help with that.

The other issue is that Windows 8 is very relucant to cede control over boot management (surprise!). I first tried installing refind_x64.efi as \EFI\Boot\bootx64.efi on the ESP. (On many EFI systems a file of that name will automatically take priority.) No go, Windows still took control of the boot. Then I tried using bcdedit under Windows to make refind the default boot manager. That didn't work either. Roderick Smith (the refind guy) remarks that on some systems \EFI\Microsoft\Boot\bootmgfw.efi is somehow "hard-wired" as the boot manager. That appears to be the case on this ThinkPad. You can work around this by moving all files in \EFI\Microsoft\Boot up into \EFI\Microsoft, deleting the (now empty) directory \EFI\Microsoft\Boot, and installing the refind files in \EFI\Boot, with refind_x64.efi renamed as bootmgfw.efi. Note that refind finds Microsoft's bootmgfw.efi in its new location, so Windows can still be booted OK.)

An alternative approach, I suppose, would be to let Windows manage the boot and find a way of adding a Linux entry (via bcdedit?). But personally I rarely run Windows and much prefer to have the PC managed by open-source tools.

False start

Truth in advertising: I must admit having made a false start in attempting to get Linux and Windows 8 dual-booting, and I thank Peter at the WFU Help Desk for patiently reloading Windows onto the machine so I could try again.

I'm not sure precisely what went wrong the first time, but I used ntfsresize and gparted from SystemRescue (rather than the Windows tools) to resize the main Windows NTFS partition, and I ended up with a working Linux system but no Windows. (The message on trying to boot Windows was "Your PC needs to be repaired".) I may have misused the third-party tools, but for anyone else contemplating this sort of thing I would strongly recommend letting Windows 8 resize its C drive.

Details

Most people are likely to install Linux using a distribution, but in case it's of help to anyone, here are some details on the dual-boot scheme I have in place. All the relevant files live on the EFI System Partition (/dev/sda3 on my machine). I mount this when needed via the following line in /etc/fstab:

/dev/sda3       /boot/efi       vfat    noauto          0       0

refind: I'm using files from the refind-bin-0.7.1 package, installed in \EFI\Boot on the ESP. The files in place here are refind_x64.efi, renamed as bootmgfw.efi, refind's icons and keys subdirectories, and the configuration file refind.conf. The sample config file is well commented. Mine looks like this:

# refind.conf
timeout 20
dont_scan_files bootmgr.efi,memtest.efi
scan_all_linux_kernels 0
default_selection elilo
# Trial Linux (EFI stub) entry. Sadly it doesn't work :-(
menuentry Linux {
	loader \EFI\linux\bzImage.efi
	options "ro root=/dev/sda5 rootfstype=ext4 net.ifnames=0"
	disabled
}

elilo: Here are the current contents of my \EFI\elilo directory:

elilo.conf
elilo.efi
vmlinuz-3.10.6
vmlinuz-3.10.7

elilo.efi is a copy of elilo-3.16-x86_64.efi from the elilo-3.16 package. The vmlinuz files are kernel bzImages, built with the following settings for EFI-related variables in the Linux .config file:

CONFIG_EFI_PARTITION=y
CONFIG_EFI=y
# CONFIG_EFI_STUB is not set
CONFIG_FB_EFI=y
CONFIG_EFI_VARS=m
CONFIG_EFI_VARS_PSTORE=m
CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE=y
CONFIG_EFIVAR_FS=m

And my elilo.conf reads thus:

# elilo.conf
root=/dev/sda5
chooser=simple
verbose=1
delay=30
read-only
default=Linux_3.10.7
#
# current kernel
  image = vmlinuz-3.10.7
  append = "rootfstype=ext4 net.ifnames=0"
  label = Linux_3.10.7
#
# previous kernel
  image = vmlinuz-3.10.6
  append = "rootfstype=ext4 net.ifnames=0"
  label = Linux_3.10.6

Windows: I moved the entire original content of \EFI\Microsoft\Boot up into \EFI\Microsoft. The file \EFI\Microsoft\bootmgfw.efi is automatically detected by refind and added to its boot menu.

One little nice thing about refind is that if you plug in a bootable USB stick it gets added to the boot menu automatically, so you don't have to pump F12 to boot from this medium.