Intaling Arch Linux on Thinkpad X1 Carbon (6th GEN)

· 14 min

While I am having many hardware troubles with my MacBook, I found a special priced X1 Carbon. So I decided to try to switch from macOS to Linux. This is a log I that I installed Arch Linux on my laptop.

I defined my goal for this installation process as that Google with my voice and watch a YouTube video online, which requires all input and output setup (except camera).

DISCLAIMER: I am not responsible for any damage and loss of data.

The machine spec:

DeviceDescription
Processor8th Gen Intel® Core™ i7-8650U with vPro™ (1.90GHz, up to 4.20GHz with Turbo Boost, 8MB Cache)
Operating SystemWindows 10 Pro 64
Display Type14.0" HDR WQHD (2560 x 1440) IPS, glossy with Dolby Vision™, 500 nits
Memory16GB LPDDR3 2133 MHz (Soldered)
Hard Drive1TB SSD PCIe
GraphicsIntegrated Intel® UHD 620
Camera720p HD
Fingerprint ReaderIncluded
WirelessIntel® Dual Band 8265 AC (2 x 2) & Bluetooth® 4.1 with vPro™

References

Without these posts/videos, I would not be able to install Arch. Truly appreciate the people who shared such great information.

Create Live Environment Disk

Download the Arch Linux

You can download the image from the official Arch Linux - Downloads. I used BitTorrent and it did not take more than an hour. I used only md5 hash to verify the image since gpg didn’t work in my environment.

Burn to a disk (USB)

I used a USB drive to store the image. The flow is really easy thanks to the great wiki. So I just followed the macOS section on USB flash installation media - ArchWiki.

BIOS Setting

We need to make changes to the BIOS menu to avoid some issues during/after the installation. To enter the BIOS setting menu, press [Enter] during the splash screen (Lenovo logo on a black background) then, press F1 to on a blue screen menu. All you need to do is follow. I picked from the wiki page. It is probably changed so you should check the wiki anyway.

  • Config -> Power -> Sleep State - Set to "Linux"
  • Config -> Thunderbolt BIOS Assist Mode - Set to "Enabled"
  • Security -> UEFI BIOS Update Option
    • both Flash BIOS Updating by End-Users and Windows UEFI Firmware Update must be enabled.
  • Security -> Secure Boot - Set to "Disabled"

When you are done, press F10 to apply the configuration and reboot the machine. Don’t forget to plug the live USB drive for the next step

Boot From The USB

Press F12 during the splash screen to enter the boot menu. Then select the live USB device. If the system is successfully booted, a command-line interface appears.

Before continue, there are some small tips.

Change the font size

The default font size is too small for the Thinkpad display. So I changed the font by run setfont sun12x22. This is the largest font I could find at the moment.

Connect to The Internet Though a WiFi Network

Even if you don’t have a wired connection, no need to be worried. The live environment has many useful tools built-in. You just need to run the wifi-menu command to connect to an access point. You can send ping to make sure the connection (ping -c 1 archlinux.org).

Optimize pacman

We are going to install a bunch of packages with pacman. So it’s better to optimize the mirrorlist beforehand. The updated mirrorlist will be copied to the newly installed system.

  1. update pacman database pacman -Syy
  2. install reflector pacman -S reflector
  3. make a backup copy for in case cp /etc/pacman.d/mirrorlist /etc/pacman.d/mirrorlist.backup
  4. reflector -c <YOUR COUNTRY> -l 20 -f 12 --save /etc/pacman.d/mirrorlist
    • You can see all the available options by run it with --help option.
    • reflector --list-countries shows you the available list of countries.
    • You can select arbitrary number of countries like this: reflector -c CA -c US -l 20 -f 12 --save /etc/pacman.d/mirrorlist

Check Batterly Life

You can know how much batterly remaining by run this command.

cat /sys/class/power_supply/BAT0/capacity

Partitioning

Basically, I followed this grate guideline which uses LVM and encryption with Luks for the main partition. Since I didn’t know much about partitioning, the following links are worth reading to get to know about it.

We can use fdisk -l and lsblk to see the partition and blocks.

Create Partition

I used cgdisk instead of gdisk which has a more user-friendly UI.

  1. Run cgdisk /dev/nvme0n1 (your device name may be different)
  2. Press d to delete all existing partitions
  3. Press n to create a new partition (size: 512M, type: ef00, name: “efi”)
  4. Press n to create a new partition (size: all of remaining, type: 8e00, name: “arch”)
  5. Press w to write to the disk
  6. Press q to quit the session

Now run fdisk -l shows disk as like below:

DeviceStartEndSectorsSizeType
/dev/nvme0n1p1204810506231048576512MEFI System
/dev/nvme0n1p2105062420004092301999358607953.4GLinux LVM

Encrypt the LVM partition

Encryption will be done with the command below.

cryptsetup luksFormat /dev/nvme0n1p2

You should carefully check the partition. It is the LVM partition, the bigger one.

Create Logical Volumes

Next, we are going to create logical volumes within the encrypted LVM to separate / (root) and /home and swap.

cryptsetup open --type luks /dev/nvme0n1p1 arch
pvcreate /dev/mapper/arch
vgcreate arch /dev/mapper/arch
lvcreate -L8G arch -n swap
lvcreate -L64G arch -n root
lvcreate -l 100%FREE arch -n home

You can see the volume layout with lsblk.

nvme0n1         259:0    0 953.9G  0 disk
├─nvme0n1p1     259:1    0   512M  0 part
└─nvme0n1p2     259:2    0 953.4G  0 part
  └─arch        254:0    0 953.4G  0 crypt
    ├─arch-swap 254:1    0     8G  0 lvm
    ├─arch-root 254:2    0    64G  0 lvm
    └─arch-home 254:3    0 881.4G  0 lvm

Mount The Created Volumes

Format all partitions and volumes we created in the previous section.

 mkfs.vfat -F32 -n EFI /dev/nvme0n1p1
 mkfs.ext4 /dev/mapper/arch-root
 mkfs.ext4 /dev/mapper/arch-home
 mkswap /dev/mapper/arch-swap

Then mount it at respectable positions.

mount /dev/mapper/arch-root /mnt
mkdir /mnt/home
mount /dev/mapper/arch-home /mnt/home
swapon /dev/mapper/arch-swap
mkdir /mnt/boot
mount /dev/nvme0n1p1 /mnt/boot

Install

Now we are ready to install Arch! Though I chose to stick with linux, you can choose to install linux-lts if you prefer stability.

pacstrap /mnt base linux linux-headers linux-firmware

And write fstab before we forget.

genfstab -U -p /mnt >> /mnt/etc/fstab
cat /mnt/etc/fstab

We all done in the live environment. Let’s move to the installed system to set it up.

arch-chroot /mnt

Initial Ramdisk

Before keep going, install man and an editor, vim (any other editor is fine though). man helps us A LOT for the rest of the installation process. When you have any questions about the system, you can run man instead of googleing.

pacman -S man vim
alias vi=vim

Install packages that we need to setup the bootloader.

pacman -S intel-ucode lvm2

Edit /etc/mkinitcpio.conf to modify HOOKS. Add encrypt lvm2 resume before filesystems and move keyboard to before autodetect for in case of using external keyboard.

HOOKS=(base udev keyboard autodetect modconf block encrypt lvm2 resume filesystems fsck)

Then create an initial ramdisk.

mkinitcpio -p linux

I had warnings below, but I ignored them since I don’t think X1 Carbon has those devices. (See also [SOLVED] WARNING: Possibly missing firmware - ArcoLinux -D -B Forum)

Possibly missing firmware for module wd719x
Possibly missing firmware for module aic94xx

Bootloader (systemd-boot)

We are going to use systemd-boot because it’s on the system in default. Also, it seems much simpler than grub. The setup is simple. However, the bootloader is important like I cannot emphasize enough. If you messed the bootloader, the system cannot be booted. Which you will be ended up the emergency shell. So I put the links which helped me to figure out the problems I had.

Ensure the boot partition, nvme0n1p1 in my case, is mounted on /boot by running lsblk. Then run bootctl to install the files for the bootloader.

lsblk
bootctl --path=/boot install

Next, create a file /boot/loader/entries/arch.conf as follow. This is the bootloader entry for the Arch system.

title Arch Linux
linux /vmlinuz-linux
initrd /intel-ucode.img
initrd /initramfs-linux.img
options cryptdevice=UUID=d00daa66-5137-4249-aa26-0ff482a6164d:arch root=/dev/mapper/arch-root resume=/dev/mapper/arch-swap rw intel_pstate=no_hwp

The cryptdevice=UUID=d00daa66-5137-4249-aa26-0ff482a6164d:arch part should be different in your environment. You need to set the block id of the encrypted partition as the value of cryptdevice. (You can know it with blkid.)

I ended up writing shell scripts. I uploaded the script on Gist. With this script, it’s not possible to make typos if you have the same partition layout.

curl -L https://git.io/JexpR| sh > /boot/loader/entries/arch.conf

Finally, Verify boot setting. If the command shows errors, something is wrong. Even if there is no error, it possibly have issues.

bootctl --path=/boot list

I had an error that says: “intel-ucode.img Not Found”. So I ran pacman -S intel-ucode again.

Network Configuration

The current connection is relying on the live environment. We are gong to lose it after the reboot. So let’s set up it for the machine using networkmanager.

pacman -S wpa_supplicant networkmanager network-manager-applet dialog
systemctl enable NetworkManager.service

Also configure hostname and the hosts file before we forget.

echo arch-x1 > /etc/hostname
vim /etc/hosts

the hosts file shold be something like this:

127.0.0.1    localhost
::1          localhost
127.0.1.1    arch-x1.localdomain arch-x1

Optimize pacman (again)

Same reason as the network, we need to configure it for the newly installed system. Do the same as earlier.

pacman -Syy
pacman -S reflector
cp /etc/pacman.d/mirrorlist /etc/pacman.d/mirrorlist.backup
reflector -c <YOUR COUNTRY> -l 20 -f 12 --save /etc/pacman.d/mirrorlist
# e.g. reflector -c CA -c US -l 20 -f 12 --save /etc/pacman.d/mirrorlist

Reboot The Machine

We are almost there. The last thing we need to do before the reboot is chaning the root password.

passwd

Now your Arch should be ready. Run exit (or type C-d) to exit fro mthe sytem, and run reboot to reboot the machine. If the system configured properly, you will be prompted for the encrypted disk password and then you can log in as root user. CONGRATS! You have installed Arch Linux! 🎉🎉🎉

If You Dropped Into Emergency Shell

I have dropped into the emergency shell many times because of the incorrect boot loader setting. If you are dropped into it too, don’t worry. You can make it right. First, you should read the error message carefully and Google it. You may find exactly the same situation and the solution for it.

After finding a solution, or to find the cause, you need to enter live environment to make changes to the system. So run reboot -f to reboot the machine and press F12 to choose the boot disk.

On the live environment, you can manually mount the blocks we made before.

  1. open the encrypted block cryptsetup open --type luks /dev/nvme0n1p1 arch
  2. mount the root mount /dev/mapper/arch-root /mnt/
  3. mount the boot block mount /dev/nvme0n1p1 /mnt/boot
  4. mount home directory if needed mount /dev/mapper/arch-home /mnt/home
  5. swap if needed swapon /dev/mapper/arch-swap

If the system is not able to boot, the problem is probably around the boot loader. So you may not need to mount /home and swap. Once you mount the blocks properly, you can enter the system with arch-chroot /mnt.

The live environment is also useful when you forget to install some packages to connect to the internet.

System Setup

After installing the Arch system, now we need to install and set up applications. Let’s connect to the internet first. If you followed this post, nmcli command should be available.

  • list available devices nmcli device
  • list SSID nmcli device wifi
  • connect to a SSID nmcli device wifi connect <SSID> password <password>

Timezone

Set timezone based on IP address.

timedatectl set-timezone $(curl --fail https://ipapi.co/timezone)
hwclock --systohc

Since we are using NetworkManager, we can add a hook to automatically update the timezone. Create a file /etc/NetworkManager/dispatcher.d/09-timezone as an executable file (chmod 0755).

#!/bin/sh
case "$2" in
  up)
    timedatectl set-timezone "$(curl --fail https://ipapi.co/timezone)"
  ;;
esac

Source: System time - ArchWiki

Localization

Edit /etc/locale.gen to uncomment en_US.UTF-8 UTF-8 and generate it with locale-gen. And set the system locale.

locale-gen
echo LANG=en_US.UTF-8 > /etc/locale.conf

Disable root User Login

The root user can do anything on your sytem. It is very dangerous if you keep it open. So let’s disable it and create a normal user for daily use and use sudo to obtain permission when needed.

Install sudo with pacman -S sudo and configure it with visudo. (If the command complains “no editor found”, you can use specify an editor with EDITOR=vim visudo.)

On the sudoers file, uncomment the line begin with #%wheel.

## Uncomment to allow members of group wheel to execute any command
%wheel ALL=(ALL) ALL

Add a user for yourself with a secure password.

useradd -m -g users -G wheel <USER>
passwd <USER>

To ensure if all are configured properly, exit the session and log-in as the new user.

  1. exit or C-D
  2. login as the user created
  3. sudo echo OK (it should prompt you to input password)

If all succeed, we are ready to disable root login.

sudo passwd -l root

Thinkpad Stuff

  1. Verify S3

    We configured BIOS at the very beginning of the installation process. Ensure S3 is available.

    dmesg | grep -i "acpi: (supports"
    

    If it “supports” S3. You are all good.

  2. Throttling fix

    sudo pacman -S throttled
    sudo systemctl enable --now lenovo_fix.service
    

    Source: Lenovo ThinkPad X1 Carbon (Gen 6) - ArchWiki

  3. BIOS Update

    I personally don’t want to take risks, especially after having a hard time with system installation. But the informations are on the wiki: Lenovo ThinkPad X1 Carbon (Gen 6) - ArchWiki.

  4. Power management

    sudo pacman -S tlp
    sudo systemctl enable --now tlp.service
    

GUI Environment

We have many options for the GUi environment. I decieded to go with KDE because KDE is highly customizable. You can even make it like this) - So cool, eh?

sudo pacman -S xf86-video-intel xorg xorg-xinit plasma

It asks you which backend to use. I chose VLC as it is recommended on “Which backend should I choose?

We also need some applications.

sudo pacman -S konsole dolphin firefox

Lastly, you need to configure xorg to launch KDE. Create ~/.xinitrc file with the content:

#!/bin/sh

userresources=$HOME/.Xresources
usermodmap=$HOME/.Xmodmap
sysresources=/etc/X11/xinit/.Xresources
sysmodmap=/etc/X11/xinit/.Xmodmap

# merge in defaults and keymaps

if [ -f $sysresources ]; then
    xrdb -merge $sysresources
fi

if [ -f $sysmodmap ]; then
    xmodmap $sysmodmap
fi

if [ -f "$userresources" ]; then
    xrdb -merge "$userresources"
fi

if [ -f "$usermodmap" ]; then
    xmodmap "$usermodmap"
fi

# start some nice programs

if [ -d /etc/X11/xinit/xinitrc.d ] ; then
 for f in /etc/X11/xinit/xinitrc.d/?*.sh ; do
  [ -x "$f" ] && . "$f"
 done
 unset f
fi

export DESKTOP_SESSION=plasma
exec startplasma-x11

That is it! You can launch KDE with startx.

More Settings

These settings/preferences below are mostly optional.

Audio

Built-in speaker and headphone jack work with these packages. plasma-pa is a front-end for KDE.

sudo pacman -S pulseaudio pulseaudio-alsa plasma-pa

To support Bluetooth headphone (I’m using qc35), we need extra packages and some tweaks. (source: bose qc 35 - arch linux.txt)

sudo pacman -S pulseaudio-bluetooth bluez bluez-utils bluez-libs bluedevil
sudo btmgmt ssp of
sudo gpasswd -a <USER> lp
sudo systemctl enable bluetooth.service

Then reboot to refresh all status. (I have no idea which process needs to be rebooted so just reboot the machine.)

Keyboard Settings

  1. Swap Ctrl and Caps lock

    I use Emacs and have an addiction to its keybindings.

    System Settings -> Hardware -> Input Device -> Keyboard -> Advanced

    • Check Caps Lock behavior -> Caps Lock is also Ctrl
  2. Keybaord Repeat

    System Settings -> Hardware -> Input Device -> Keyboard -> Hardware -> Keyboard Repeat

    • Delay: 200 ms
    • Rate: 50.00 repeats/s
  3. Disable Hotkey (Fn)

    This setting is in the BIOS setting. So you need to reboot the machine, and press [Enter] during the splash screen. In the BIOS setting, set Config -> Keybaord/Mouse -> F1-F12 as Primary Function as “Enabled”. Then F10 to save and exit.

Display Resolution

You can change the display resolution and scale from System Settings -> Hardware -> Display and Monitor -> Display Configuration. I set them to:

| Resolution | 2560x1440 | | Global Scale | 1.4x |

AUR with Yay

yay is a package management utility for AUR (Arch User Repository). With this tool, we can install packages from AUR in the same way as using pacman.

To install yay, we need base-devel and git.

sudo -S pacman -S --needed base-devel git

And install yay.

mkdir -p ~/code/oss/yay
git clone https://aur.archlinux.org/yay.git ~/code/oss/yay
cd !$
makepkg -sic

Now we can install packages from AUR with yay -S <package>.

Closing

That is it! There more to do to be ready for the day-to-day development. Most of it are/will be covered in my dotfiles on Github.


Shota Senga

@__senta

Software Developer who enjoys beer 🍻 and music 🎧