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

· 15 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™

Reference

Thanks to the posts below and videos, I was able to install Arch Linux on my laptop. I appreciate the people who shared such great information. So I wish this post will be valuable for someone, somehow.

Create Live Environment Disk

Download the Arch Linux

You can download the image from the official page Arch Linux - Downloads. I used BitTorrent and it didn’t take more than an hour. To verify the image, I used only md5 hash since gpg didn’t work in my environment. Verifying the image is very important. Verifying the image is very important. If the downloaded image has modified, the system is going to be hacked.

Write image to a disk

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 luksOpen /dev/nvme0n1p2 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
ln -s /usr/bin/vim /usr/bin/vi

Install packages that we need to setup the bootloader.

pacman -S intel-ucode lvm2

Edit /etc/mkinitcpio.conf to added encrypt lvm2 reusable before filesystems and moved keyboard before autodetect 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 the devices. At least, I don’t have a problem while using the machine. (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 more simple 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 with lsblk. If it looks fine, 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

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

Because of many and many confusions, 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

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

At this point, we have an internet connection thanks to the live environment. But the system we are making doesn’t have it. So install networkmanager and it’s relevant.

pacman -S wpa_supplicant networkmanager network-manager-applet dialog

And enable it as a service.

systemctl enable NetworkManager.service

Set hostname and hosts file while we are here.

echo myhostname > /etc/hostname

Edit /etc/hosts as follow.

    127.0.0.1    localhost
    ::1          localhost
    127.0.1.1    myhostname.localdomain myhostname

Reboot The Machine

We are almost there. Before get out of the system, change the password for the root user.

passwd

Now let’s try to boot the installed Arch. Run exit (or type C-d) to exit, then run reboot. 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! Congratulate yourself!! 🎉🎉🎉

If You Dropped Into Emergency Shell

I have dropped into the emergency shell many times. Because of an 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 a basic Arch system, now we need to install and set up applications. However, to do anything, we need an internet connection. If you followed this post, you should have nmcli command. With the command, you can connect to a WiFi device. If you have a wired connection, all good.

  • 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 executable (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

For better security, we should use a normal user and use sudo to obtain permission if needed. In order to do this, install it 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 all 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

Now we are ready to disble root login.

sudo password -l

From this pint, I assume we are logged in as a normal user.

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.

Power Management

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

GUI Environment

sudo pacman -S libgl xf86-video-intel xorg xorg-xinit # maybe, libgl is not needed
sudo pacman -S xf86-video-intel xorg xorg-xinit
    
sudo pacman -S plasma-desktop sddm
sudo systemctl enable sddm.service

I chose VLC. See Which backend should I choose?

Create /etc/sddm.conf.d/theme.conf with content below.

[Theme]
Current=breeze

Add support for GTK

sudo pacman -S breeze-gtk kde-gtk-config

Add applets of network and power management

pacman -S plasma-nm powerdevil

Intall applications

sudo pacman -S konsole dolphin

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 (Tested with qc35), we need extra packages and some tweaks. (Thanks to 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.)

Testing The System

sudo pacman -S firefox
  1. Open firefox and install Voice Fille
  2. Click the mic icon and say “YouTube”
  3. Play a video on YouTube! Worked!!

Only Chromium is available on the official Arch repository.

Customization

This section is personal preference stuff. So you don’t need to follow. I want to keep this for the future myself.

You can find KDE applications on KDE’s Applications - KDE.org. Add a link to Arch Wiki (application list page)

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)

    The 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

Install kscreen with pacman -S kscreen to add “Display Configuration” menu on the setting.

System Settings -> Hardware -> Display and Monitor -> Display Configuration

  • Resolution: 2560x1440
  • Global scale: 1.4x

System Settings -> Fonts -> Fonts

  • Unchecke Force font DPI

GPG and KWallet

Generate PGP key with

gpg --full-generte-key

Install KWallet Manager

sudo pacman -S kwalletmanager

SSH

pacman -S openssh
ssh-keygen -t rsa

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/arch/yay
git clone https://aur.archlinux.org/yay.git ~/code/arch/yay
cd !$
makepkg -sic

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

yay -S google-chrome dropbox

Japnese Input

Install Japanese fonts.

sudo pacman -S adobe-source-han-sans-jp-fonts

Install fcitx (input method framework) and mozc.

sudo pacman -S fcitx fcitx-mozc fcitx-configtool kcm-fcitx fcitx-im

Add below to ~/.xprofile to activate IM for the user.

export GTK_IM_MODULE=fcitx
export QT_IM_MODULE=fcitx
export XMODIFIERS="@im=fcitx"

Then re-login to the system. You can configure keybindings and appearance through System Settings -> Regional Settings -> Input Method.

Source: Input Japanese using uim - ArchWiki

Emoji

Install Emoji fonts from the repository.

sudo pacman -S noto-fonts-emoji

Then we need to add emoji config. I have found a good resource here. Follow the instruction, then open Get Emoji with your browser to check if all emojis are properly rendered.

Developement Environment

  • yay -S emacs google-chrome dropbox
  • pacman -S ripgrep zip

Python

sudo paman -S pyenv python-pipenv
pyenv install 3.7.4
pyenv global 3.7.4
pyenv rehash
pip install --upgrde pip
python --version

Ruby

Install rbenv and ruby-build.

yay -S rbenv ruby-build
rbenv install 2.7.0
rbenv global 2.7.0
rbenv rehash
ruby --version

Node

onvm use v12
node --version

Desktop Environment

Finally, we have made the system work. There are so many things you can do to enhance your Arch. One thing I did is the desktop customization with KDE. I prefer KDE over Gnome because of its flexibility though it doesn’t support Emacs like keybindings. This article) is the one I followed to make it look better.


Shota Senga

@__senta

Software Developer who enjoys beer 🍻 and music 🎧