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:
|Processor||8th Gen Intel® Core™ i7-8650U with vPro™ (1.90GHz, up to 4.20GHz with Turbo Boost, 8MB Cache)|
|Operating System||Windows 10 Pro 64|
|Display Type||14.0" HDR WQHD (2560 x 1440) IPS, glossy with Dolby Vision™, 500 nits|
|Memory||16GB LPDDR3 2133 MHz (Soldered)|
|Hard Drive||1TB SSD PCIe|
|Graphics||Integrated Intel® UHD 620|
|Wireless||Intel® Dual Band 8265 AC (2 x 2) & Bluetooth® 4.1 with vPro™|
Without these posts/videos, I would not be able to install Arch. Truly appreciate the people who shared such great information.
- installation guide - ArchWiki
- Lenovo ThinkPad X1 Carbon (Gen 6) - ArchWiki
- ejmg/an-idiots-guide-to-installing-arch-on-a-lenovo-carbon-x1-gen-6: so you wanted to install arch huh
- A detailed overview of how I installed Arch Linux on my Lenovo ThinkPad X1 Extreme, having never installed Arch before.
- Install ARCH Linux on ThinkPad X1 Carbon Gen 7 with encrypted filesystem and UEFI
- Arch Linux - Install, Configure, Tweak - YouTube
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.
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
Flash BIOS Updating by End-Usersand
Windows UEFI Firmware Updatemust 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
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).
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.
- update pacman database
- install reflector
pacman -S reflector
- make a backup copy for in case
cp /etc/pacman.d/mirrorlist /etc/pacman.d/mirrorlist.backup
reflector -c <YOUR COUNTRY> -l 20 -f 12 --save /etc/pacman.d/mirrorlist
- You can see all the available options by run it with
reflector --list-countriesshows 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
- You can see all the available options by run it with
Check Batterly Life
You can know how much batterly remaining by run this command.
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.
- Partitioning - ArchWiki
- How to partition and format a drive on Linux | Opensource.com
- A Linux user’s guide to Logical Volume Management
We can use
fdisk -l and
lsblk to see the partition and blocks.
cgdisk instead of
gdisk which has a more user-friendly UI.
cgdisk /dev/nvme0n1(your device name may be different)
dto delete all existing partitions
nto create a new partition (size: 512M, type:
ef00, name: “efi”)
nto create a new partition (size: all of remaining, type:
8e00, name: “arch”)
wto write to the disk
qto quit the session
fdisk -l shows disk as like below:
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
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
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
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.
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
/etc/mkinitcpio.conf to modify
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
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.
- systemd-boot - ArchWiki
- Persistent block device naming - ArchWiki (info about block naming and it’s expressions)
- loader.conf(5) — Arch manual pages
- Kernel parameters - ArchWiki
- dm-crypt/System configuration - ArchWiki (more about
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
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
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.
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
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.
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.
live environment, you can manually mount the blocks we made before.
- open the encrypted block
cryptsetup open --type luks /dev/nvme0n1p1 arch
- mount the root
mount /dev/mapper/arch-root /mnt/
- mount the boot block
mount /dev/nvme0n1p1 /mnt/boot
- mount home directory if needed
mount /dev/mapper/arch-home /mnt/home
- swap if needed
If the system is not able to boot, the problem is probably around the boot loader. So you may not need to mount
swap. Once you mount the blocks properly, you can enter the system with
The live environment is also useful when you forget to install some packages to connect to the internet.
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
- list SSID
nmcli device wifi
- connect to a SSID
nmcli device wifi connect <SSID> password <password>
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 (
#!/bin/sh case "$2" in up) timedatectl set-timezone "$(curl --fail https://ipapi.co/timezone)" ;; esac
Source: System time - ArchWiki
/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
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.
pacman -S sudo and configure it with
visudo. (If the command complains “no editor found”, you can use specify an editor with
On the sudoers file, uncomment the line begin with
## 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.
- login as the user created
sudo echo OK(it should prompt you to input password)
If all succeed, we are ready to disable
sudo passwd -l root
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.
sudo pacman -S throttled sudo systemctl enable --now lenovo_fix.service
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.
sudo pacman -S tlp sudo systemctl enable --now tlp.service
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
These settings/preferences below are mostly optional.
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.)
I use Emacs and have an addiction to its keybindings.
System Settings -> Hardware -> Input Device -> Keyboard -> Advanced
Caps Lock behavior -> Caps Lock is also Ctrl
System Settings -> Hardware -> Input Device -> Keyboard -> Hardware -> Keyboard Repeat
- Delay: 200 ms
- Rate: 50.00 repeats/s
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 Functionas “Enabled”. Then
F10to save and exit.
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
yay, we need
sudo -S pacman -S --needed base-devel git
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>.
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.