This is a disorganized grouping of notes on how I set up my T420. It is configured to dual-boot Windows 7 and Linux. Windows can be safely started from within VirtualBox on Linux for quick tasks, or booted normally for extended tasks or high performance. I’d say mostly these notes are intended for myself (i.e. for the next time I hose my machine) and for other users of ThinkPad laptops like my T420. Lots of information came from the Arch Linux wiki.

Installing Windows

It’s best to install Windows before Linux. I assigned the first 80GB of my 240GB SSD to Windows, activated, applied all updates, and installed my normal suite of apps:

Set up the following AutoHotKey script to run by default:

Capslock::Esc ; caps lock -> escape for Vim usage
~#t::WinMaximize, A ; maximize active

When applying updates, I had to blacklist KB3035583 to avoid the Windows 10 nag.

Installing Arch

After installing Windows and partitioning for Arch, my hard drive looked like this:

# sudo fdisk -l /dev/sda
Disk /dev/sda: 223.6 GiB, 240057409536 bytes, 468862128 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x65c12669

Device     Boot     Start       End   Sectors   Size Id Type
/dev/sda1  *         2048    206847    204800   100M  7 HPFS/NTFS/exFAT
/dev/sda2          206848 167774207 167567360  79.9G  7 HPFS/NTFS/exFAT
/dev/sda3  *    167774208 468862127 301087920 143.6G 83 Linux

TODO consider partition labels (e2label, fatlabel, etc.)

The most important pieces are the EFI partition (which may need to be larger, 550MB has been suggested) and partitions for other operating systems. The EFI partition needs to have the proper partition type and be marked bootable.

The install went something like this after partitioning and connecting to the internet within the installer environment.

# mount /dev/sda3 /mnt
# pacstrap -i /mnt base vim zsh reflector
# genfstab -U /mnt > /mnt/etc/fstab
# arch-chroot /mnt /bin/bash
# echo "en_US.UTF-8 UTF-8\n" > /etc/locale.gen
# locale-gen
# echo "LANG=en_US.UTF-8\n" > /etc/locale.conf
# ln -sf /usr/share/zoneinfo/America/Detroit /etc/localtime
# echo "MYHOSTNAME" > /etc/hostname
# hwclock --systohc --utc
# mkinitcpio -p linux
# passwd
# systemctl enable systemd-timesyncd.service

For laptop systems where I will need wifi connection after a reboot, I usually do this:

# pacman -S ifplugd iw wpa_actiond wpa_supplicant dialog dhcpcd wpa_actiond dialog
# systemctl enable netctl-ifplugd@enp0s25.service
# systemctl enable netctl-auto@wlp3s0.service

Alternatively for ethernet:

systemctl enable dhcpcd@enp0s4.service

Then install a bootloader, either GRUB as follows:

# pacman -S grub os-prober
# grub-install --recheck /dev/sda
# grub-mkconfig -o /boot/grub/grub.cfg

or systemd-boot by mounting the ESP on /boot (including the fstab change), running

# bootctl install

creating the file /boot/loader/loader.conf with the following contents:

default  arch
timeout  4
console-mode max
editor   no

creating at least one boot entry such as /boot/loader/entires/arch.conf like the following:

title   Arch Linux
linux   /vmlinuz-linux
initrd  /initramfs-linux.img
options root=LABEL=arch_os rw

and running the following:

# bootctl update

Finally, hop out of the chroot, umount everything and take the first leap of faith by rebooting.

At some point (even before the first reboot), the following also occurs:

  • Create my daily user/group (with my normal fixed GID/UID), and add the user to useful groups

    • wheel for sudo
    • uucp for serial and other hardware access
    • lp for printer access
    • audio for audio access for PulseAudio
    • optical for access to optical drives (CD/DVD reading/writing)
  • Set up any wifi profiles I need using the wifi-menu

  • Enable multilib for a daily machine by uncommenting it in /etc/pacman.conf

  • Rank mirrors by speed by installing reflector and running it:

    reflector --latest 200 --protocol http --protocol https --sort rate --save /etc/pacman.d/mirrorlist
  • Install standard console programs via pacman -S zip unzip unrar rsync wget sshfs fuseiso ntfs-3g zsh elinks tmux reptyr ack nethack mlocate unison rxvt-unicode-terminfo neomutt nmap

  • If desired, install and activate sshd (pacman -S openssh && systemctl enable sshd.service)

  • Install sudo (pacman -S sudo) and configure it by uncommenting the following line in /etc/sudoers to enable it:

    %wheel ALL=(ALL) ALL
  • Install management tools: pacman -S pkgfile, yay from the AUR (and add Color to /etc/pacman.conf)

  • Install standard development programs via pacman -S base-devel clang git ghc cabal-install c2hs texlive-most biber rubber octave gnuplot julia jupyterlab jupyterlab_server python python-lxml python-pytorch python-lxml-docs pandoc pandoc-citeproc python-pip graphviz haskell-hakyll haskell-microlens hlint python-flickrapi ruby-sass pacman-contrib glade ttf-fira-mono ttf-fira-sans ttf-roboto docker and ttf-sourcesanspro ttf-merriweather ttf-merriweather-sans ttf-ms-fonts ttf-tahoma ttf-vista-fonts ttf-juliamono pp-git exfat-dkms-git singularity-compute from the AUR. If you don’t want X11, skip octave gnuplot glade

    • add needed users to docker group
  • Normal X programs: pacman -S xorg gvim xmonad xmonad-contrib xmobar feh xcompmgr rxvt-unicode urxvt-perls firefox dillo vlc ttf-hack ttf-dejavu lxappearance xorg-xset xorg-xinit xf86-input-synaptics solaar qpdfview sigil libreoffice wireshark-gtk xclip tigervnc, and albert-lite from the AUR

  • Audio stuff: pacman -S pulseaudio pavucontrol pamixer and pulseaudio-ctl from the AUR

  • Other stuff I use: pacman -S beets cmus task xournal transmission-gtk and sunflower ruby-taskwarrior-web from the AUR

  • For parsing HTML: pup from the AUR

  • Photography apps: pacman -S darktable hugin luminancehdr nomacs python-gobject gimp inkscape

  • 3D printing apps: pacman -S openscad and freecad perl-wx slic3r icesl from the AUR (these didn’t work as of Nov 2018)

  • Install acpid and enable it (systemctl enable acpid) for volume keys

  • Install tlp and configure systemd units:

    systemctl enable tlp.service
    systemctl enable tlp-sleep.service
    systemctl mask systemd-rfkill.service
    systemctl mask systemd-rfkill.socket
  • Run tlp-stat and follow its recommendations by installing smartmontools, ethtool, acpi_call

Video drivers

To get GPU switching on the T420, I needed bumblebee nvidia-340xx nvidia-340xx-utils opencl-nvidia-340xx and the bbswitch module

Power management / battery life

cpupower 4.3-1 thinkfan 0.9.2-3 thinkfinger 0.3-8 upower 0.99.3-1

Parts of this are specific to ThinkPads

# pacman -S tlp powertop
# pacman -S tp_smapi acpi_call   # only for T420, not needed for T450s
# systemctl enable tlp
# systemctl enable tlp-sleep
# systemctl disable systemd-rfkill@.service

tweaks to grub config for i915 /etc/default/grub

pcie_aspm=force i915.i915_enable_rc6=1 enable lower power state during Intel GPU idle UbuntuPowerSave. Side effects unknown. power savings unknown.

i915.i915_enable_fbc=1 framebuffer compression, as much as 0.6W saved UbuntuPowerSave. May cause graphic artifacts.

i915.lvds_downclock=1 reduce LVDS refresh rate (built-in screen). Side effect might be screen flickering if laptop does not support this option (but T420 does). Power savings around 0.1 watt. UbuntuPowerSave

Console font

Requires installation of: pacman -S terminus-font


Other tweaks / preferences

Use nemo as a file manager without desktop icons

# gsettings set org.nemo.desktop show-desktop-icons false
# gsettings set org.cinnamon.desktop.default-applications.terminal exec urxvt

Disable beeping PC speaker:

# echo "blacklist pcspkr" > /etc/modprobe.d/nobeep.conf

Booting the Windows partition within VirtualBox

pacman -S virtualbox virtualbox-host-modules-arch

  • create linear map device for the VM (fdisk -l gives the sizes for this)
  • use fdisk to set disk id the same as phy disk
  • install guest additions inside Windows
  • save product key to C:.txt for future activation needs

The fdisk output for this drive is

Disk /dev/sda: 223.6 GiB, 240057409536 bytes, 468862128 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x65c12669

Device     Boot     Start       End   Sectors   Size Id Type
/dev/sda1  *         2048    206847    204800   100M  7 HPFS/NTFS/exFAT
/dev/sda2          206848 167774207 167567360  79.9G  7 HPFS/NTFS/exFAT
/dev/sda3  *    167774208 468862127 301087920 143.6G 83 Linux

So the text file should be created as follows:

0 2048 linear /dev/loop0 0
2048 204800 linear /dev/sda1 0
206848 167567360 linear /dev/sda2 0

and the preparation script, run once per boot:

sudo losetup /dev/loop0 boot.mbr
sudo modprobe dm_mod
sudo dmsetup create virtual_windows_disk windows_vm_disk_def
sudo modprobe vboxdrv
sudo modprobe vboxnetadp
sudo modprobe vboxnetflt
sudo chown alhirzel:alhirzel /dev/mapper/virtual_windows_disk

Ideas for the future

Turn one of my awesome tags into Windows,

Color calibration

TODO fix the Bumblebee error in journalctl

Other stuff to incorporate


options snd-hda-intel model=thinkpad

Change /etc/modprobe.d/thinkpad-volume-fix.conf according to, otherwise the volume controls on the keyboard will sometimes lock up

options thinkpad_acpi volume_control=1

Battery life woes

Piano - pacman -S alsa-utils rosegarden audacity rt-tests, TODO maybe switch to JACK from Pulse? needs 1kHz-tick kernel and PREEMPT. if cyclictest --smp -p98 -m ever tops 1000 max, then it is time for hard real-time

Running fwts first



cups and cups-pdf systemctl enable org.cups.cupsd.service

gmvault - for gmail backup?

Modelica - install openmodelica-git and ompython from the AUR (I maintain OMPython, pacman -S pacman-contrib is handy for updpkgsums)

Embedded development - platformio, esptool, avrdude, the udev rules, etc.

Splash screen

install plymouth and plymouth-theme-arch-beat from the AUR, and enable the latter with the command sudo plymouth-set-default-theme -R arch-beat. Add plymouth to /etc/mkinitcpio.conf HOOKS line after base and udev. add i915 to MODULES line. in /etc/plymouth.conf make sure to set the wait to 0s. Add the following kernel options: quiet loglevel=3 vga=current rd.udev.log-priority=3 vt.global_cursor_default=0 i915.fastboot=1 splash

dhcpcd-hook-ntpdate mcidasv-bin

for GPS data parsing, install gpsbabel gpxsee


Rough outline:

  1. install bluez and bluez-utils
  2. enable bluetooth.service
  3. install pulseaudio-bluetooth