Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save dfd/22c6dbe03a15c23c01540660c9730a5d to your computer and use it in GitHub Desktop.
Save dfd/22c6dbe03a15c23c01540660c9730a5d to your computer and use it in GitHub Desktop.
Lenovo z13 Void Linux Field Notes

Void Linux Field Notes (Lenovo z13 Edition)

This contains the notes from my installation of Void Linux onto my Lenovo z13 (gen1) laptop1 with the following specs:

  • AMD Ryzen™ 7 PRO 6860Z
  • 13.3" 2.8K (2880 x 1800) OLED
  • 32 GB LPDDR5 6400MHz
  • Integrated AMD Radeon™ 680M Graphic
  • WiFi 6E 802.11AX
  • WWAN Fibocom L860-GL-16 4G CAT16

Notes about this installation:

  • LUKS encryption excluding ESP
  • BTRFS (best practices based on Snapper layout)
  • swapfile offset for hibernate to disk
  • Grub + Grub Btrfs for booting into snapshots
  • Baseline services for post-configuration

Preparation (pre-bootstrap)

# Set the device we will use (i.e. /dev/nvme0n1)
DEVICE=/dev/nvme0n1

# Enter the bash shell
bash

xbps-install -Su xbps gptfdisk btrfs-progs wget cryptsetup git

sgdisk --zap-all $DEVICE
sgdisk --clear \
--new=1:0:+300MiB --typecode=1:ef00 --change-name=1:EFI \
--new=2:0:0 --typecode=2:8300 --change-name=2:ROOTFS \
$DEVICE

mkfs.vfat -F32 -n EFI /dev/disk/by-partlabel/EFI

cryptsetup --type luks2 --cipher aes-xts-plain --hash sha512 --key-size 512 --pbkdf pbkdf2 --pbkdf-force-iterations 1000 --use-urandom --verify-passphrase luksFormat /dev/disk/by-partlabel/ROOTFS

cryptsetup luksOpen /dev/disk/by-partlabel/ROOTFS cryptroot

mkfs.btrfs -L BTRFS /dev/mapper/cryptroot -f && \
mount -L BTRFS /mnt && \
btrfs sub create /mnt/@ && \
btrfs sub create /mnt/@home && \
btrfs sub create /mnt/@boot && \
btrfs sub create /mnt/@vtmp && \
btrfs sub create /mnt/@vcache && \
btrfs sub create /mnt/@vlog && \
btrfs sub create /mnt/@vdocker && \
btrfs sub create /mnt/@.swap && \
btrfs sub create /mnt/@.snapshots && \
umount /mnt

OPTS=rw,noatime,compress-force=zstd:1,ssd,space_cache=v2,autodefrag && \
SWOPTS=rw,noatime,compress-force=none,ssd,space_cache=v2,autodefrag && \
mount -o $OPTS,subvol=@ -L BTRFS /mnt && \
mkdir -p /mnt/{home,boot,var/tmp,var/cache,var/log,var/lib/docker,.swap,.snapshots,efi,tmp}

mount -o $OPTS,subvol=@home -L BTRFS /mnt/home && \
mount -o $OPTS,subvol=@boot -L BTRFS /mnt/boot && \
mount -o $OPTS,subvol=@vtmp -L BTRFS /mnt/var/tmp && \
mount -o $OPTS,subvol=@vcache -L BTRFS /mnt/var/cache && \
mount -o $OPTS,subvol=@vlog -L BTRFS /mnt/var/log && \
mount -o $OPTS,subvol=@vdocker -L BTRFS /mnt/var/lib/docker && \
mount -o $OPTS,subvol=@.snapshots -L BTRFS /mnt/.snapshots && \
mount -o $SWOPTS,subvol=@.swap -L BTRFS /mnt/.swap && \
mount -o rw,noatime -L EFI /mnt/efi

btrfs filesystem mkswapfile --size 34g /mnt/.swap/swapfile && \
swapon /mnt/.swap/swapfile

mount -o x-mount.mkdir --rbind --make-rslave /dev /mnt/dev && \
mount -o x-mount.mkdir --types proc /proc /mnt/proc && \
mount -o x-mount.mkdir --bind --make-slave /run /mnt/run && \
mount -o x-mount.mkdir --rbind --make-rslave /sys /mnt/sys && \
mount -o x-mount.mkdir --rbind --make-rslave /sys/firmware/efi/efivars /mnt/sys/firmware/efi/efivars

Bootstrap

REPO=https://repo-default.voidlinux.org/current && \
ARCH=x86_64

mkdir -p /mnt/var/db/xbps/keys && \
cp /var/db/xbps/keys/* /mnt/var/db/xbps/keys/

XBPS_ARCH=$ARCH xbps-install -S -r /mnt -R "$REPO" base-system base-devel linux linux-headers cryptsetup btrfs-progs dosfstools linux-firmware linux-firmware-qualcomm lz4 zstd \
acpid elogind dbus-elogind polkit-elogind wireplumber-elogind xscreensaver-elogind \
grub-x86_64-efi grub-btrfs grub-terminus grub-btrfs-runit terminus-font \
tpm2-tools efibootmgr efitools efivar gummiboot-efistub sbctl fwupd fwupd-efi \
sudo git nano wget curl rsync rclone btrbk restic autorestic dropbear bearssl byacc muon samurai cronie chrony socklog-void apparmor runit-void-apparmor earlyoom v4l-utils xtools cups cups-filters cups-pdf gutenprint hplip system-config-printer cups-pk-helper \
iwd NetworkManager ModemManager openresolv bluez avahi nss-mdns tailscale wireless_tools \
pipewire wireplumber alsa-firmware alsa-tools alsa-pipewire pulseaudio-utils libjack-pipewire easyeffects gstreamer1-pipewire libspa-bluetooth \
xdg-user-dirs xdg-desktop-portal xdg-dbus-proxy xdg-utils \
xorg mesa-dri vulkan-loader mesa-vulkan-radeon mesa-vaapi mesa-vdpau \
lxc lxd libvirt containerd docker docker-compose

Preconfigure

HOSTNAME=localhost
TZ=UTC
LOCAL_USER=dummy

### Base configs...
# Change shell and set root passwd
xchroot /mnt chsh -s /bin/bash && \
xchroot /mnt passwd

# Setup hostname and hosts
echo $HOSTNAME > /mnt/etc/hostname && \
echo -e "127.0.0.1\tlocalhost\n::1\t\tlocalhost\n127.0.1.1\t$HOSTNAME.localdomain\t$HOSTNAME" > /mnt/etc/hosts && \
sed -i 's/^#HOSTNAME=.*$/HOSTNAME="'$HOSTNAME'"/' /mnt/etc/rc.conf

# Set timezone
xchroot /mnt ln -sf /usr/share/zoneinfo/$TZ /etc/localtime && \
xchroot /mnt hwclock --systohc

# Setup locale
sed -i 's/#en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /mnt/etc/default/libc-locales && \
echo -e 'export LANG="en_US.UTF-8"\nexport LC_COLLATE="C"' > /mnt/etc/locale.conf && \
sed -i 's/^#KEYMAP=.*$/KEYMAP="us"/' /mnt/etc/rc.conf
sed -i 's/^#FONT=.*$/FONT="ter-132b"/' /mnt/etc/rc.conf
xchroot /mnt xbps-reconfigure -f glibc-locales

# Fonts
xchroot /mnt ln -s /usr/share/fontconfig/conf.avail/70-no-bitmaps.conf /etc/fonts/conf.d/ && \
xchroot /mnt xbps-reconfigure -f fontconfig

# Swap
# https://wiki.gentoo.org/wiki/Swap#Swappiness
echo vm.swappiness=10 > /mnt/usr/lib/sysctl.d/99-swappiness.conf

# SSD
# https://wiki.gentoo.org/wiki/SSD#cron
echo -e '#!/bin/sh\n\nfstrim /' > /mnt/etc/cron.weekly/fstrim && \
xchroot /mnt chmod u+x /etc/cron.weekly/fstrim


### User Account Setup
# Create an entry for anyone in the wheel group and then add a new user to the system.
echo "%wheel ALL=(ALL:ALL) NOPASSWD: ALL" > /mnt/etc/sudoers.d/01_wheel && \
xchroot /mnt useradd -m -g users -G wheel -s /bin/bash $LOCAL_USER && \
xchroot /mnt usermod -a -G video,audio,input,disk,storage,optical,lp,scanner,dbus,tty,disk,bluetooth,socklog,plugdev,users,xbuilder,lxd,libvirt,docker $LOCAL_USER && \
xchroot /mnt passwd $LOCAL_USER

### Networking
## https://wiki.archlinux.org/title/NetworkManager#Use_openresolv
mkdir -p /mnt/etc/NetworkManager/conf.d && \
echo -e "[main]\nrc-manager=resolvconf" > /mnt/etc/NetworkManager/conf.d/rc-manager.conf
## https://wiki.archlinux.org/title/NetworkManager#Using_iwd_as_the_Wi-Fi_backend
echo -e "[device]\nwifi.backend=iwd" > /mnt/etc/NetworkManager/conf.d/wifi_backend.conf
## https://wiki.archlinux.org/title/iwd#Optional_configuration
mkdir -p /mnt/etc/iwd && \
echo -e "[General]\nEnableNetworkConfiguration=false\nUseDefaultInterface=true\n[Network]\nNameResolvingService=resolvconf" > /mnt/etc/iwd/main.conf
## https://wiki.gentoo.org/wiki/Avahi#Client_Files
sed -i 's/^hosts: .*$/hosts:       	files mdns4_minimal [NOTFOUND=return] dns mdns4/' /mnt/etc/nsswitch.conf

### Fix the conflicts between acpid and elogind
mkdir -p /mnt/etc/elogind/logind.conf.d/ && \
cp /mnt/etc/elogind/logind.conf /mnt/etc/elogind/logind.conf.d/acpid.conf
## https://docs.voidlinux.org/config/power-management.html#acpid
sed -i '/#Handle/s/^#\(.*=\).*/\1ignore/' /mnt/etc/elogind/logind.conf.d/acpid.conf

### Audio baseline
mkdir -p /mnt/etc/pipewire/pipewire.conf.d && \
mkdir -p /mnt/etc/alsa/conf.d && \
xchroot /mnt ln -s /usr/share/examples/wireplumber/10-wireplumber.conf /etc/pipewire/pipewire.conf.d && \
xchroot /mnt ln -s /usr/share/examples/pipewire/20-pipewire-pulse.conf /etc/pipewire/pipewire.conf.d && \
xchroot /mnt ln -s /usr/share/alsa/alsa.conf.d/50-pipewire.conf /etc/alsa/conf.d && \
xchroot /mnt ln -s /usr/share/alsa/alsa.conf.d/99-pipewire-default.conf /etc/alsa/conf.d && \
echo "/usr/lib/pipewire-0.3/jack" > /mnt/etc/ld.so.conf.d/pipewire-jack.conf && \
xchroot /mnt ldconfig

### Install non-free
xchroot /mnt xbps-install -Su void-repo-nonfree

fstab

NOTE: There are some manual file manipulations here

git clone https://github.com/adamarbour/void-linux-genfstab.git

./void-linux-genfstab/genfstab -L /mnt -L /mnt >> /mnt/etc/fstab && \
echo "tmpfs /tmp tmpfs defaults,noatime,mode=1777,size=16G 0 0" >> /mnt/etc/fstab

### Manual changes... that I am too lazy to write sed commands for.
## Change the options for all btrfs subvolumes to the following:
## noatime,compress-force=zstd:1,ssd,space_cache=v2,autodefrag

initram

  1. Create a keyfile to unlock from grub...
dd bs=512 count=4 if=/dev/random of=/mnt/boot/crypto_keyfile.bin iflag=fullblock && \
cryptsetup luksAddKey /dev/disk/by-partlabel/ROOTFS /mnt/boot/crypto_keyfile.bin && \
xchroot /mnt chmod 000 /boot/crypto_keyfile.bin && \
xchroot /mnt chmod -R g-rwx,o-rwx /boot
  1. Configure Dracut defaults2
# Setup the crypttab to use the key
ROOTFS=$(blkid -o value -s UUID /dev/disk/by-partlabel/ROOTFS) && \
CRYPTROOT=$(blkid -o value -s UUID /dev/mapper/cryptroot) && \
echo -e "cryptroot\tUUID=$ROOTFS\t/boot/crypto_keyfile.bin\tluks" >> /etc/crypttab

cat <<EOF >> /mnt/etc/dracut.conf.d/00-defaults.conf
hostonly=yes
compress="lz4"
early_microcode=yes
show_modules=yes

force_drivers+=" amdgpu radeon "
install_items+=" /boot/crypto_keyfile.bin /etc/crypttab "
EOF

cat <<EOF >> /mnt/etc/dracut.conf.d/99-cmdline.conf
hostonly_cmdline=no
CMDLINE=(
	rw
	rd.lvm=0
	rd.md=0
	rd.dm=0
	rd.luks=1
	rd.luks.uuid=$ROOTFS
	rd.luks.allow-discards
	rd.luks.crypttab=1
	root=UUID=$CRYPTROOT
	rootfstype=btrfs
	rootflags=subvol=@
)
kernel_cmdline="\${CMDLINE[*]}"
unset CMDLINE
EOF

## Reconfigure and build the initram
xchroot /mnt xbps-reconfigure -fa

grub

xchroot /mnt /bin/bash

# I do this from inside the chroot because I ran into issues.
GRUB_MODS="luks2 btrfs part_gpt cryptodisk pbkdf2 gcry_rijndael gcry_sha512" && \
ROOTFS=$(blkid -o value -s UUID /dev/disk/by-partlabel/ROOTFS) && \
CRYPTROOT=$(blkid -o value -s UUID /dev/mapper/cryptroot)

# Modify config
sed -i '/^GRUB_ENABLE_CRYPTODISK=.*$/ d' /etc/default/grub && \
sed -i '/^GRUB_PRELOAD_MODULES=.*$/ d' /etc/default/grub && \
sed -i '/^GRUB_CMDLINE_LINUX=.*$/ d' /etc/default/grub && \
sed -i 's/^GRUB_CMDLINE_LINUX_DEFAULT=.*$/GRUB_CMDLINE_LINUX_DEFAULT="apparmor=1 security=apparmor mitigations=off nowatchdog loglevel=3 quiet"/' /etc/default/grub

echo "GRUB_ENABLE_CRYPTODISK=y" >> /etc/default/grub && \
echo "GRUB_PRELOAD_MODULES=\"$GRUB_MODS\"" >> /etc/default/grub && \
echo "GRUB_CMDLINE_LINUX=\"resume=UUID=$CRYPTROOT resume_offset=$(btrfs inspect-internal map-swapfile -r /.swap/swapfile)\"" >> /etc/default/grub

grub-install --target=x86_64-efi --boot-directory=/boot --efi-directory=/efi --bootloader-id=VOID --modules="$GRUB_MODS" --recheck && \
grub-mkconfig -o /boot/grub/grub.cfg

CRYPTOID=$(echo $ROOTFS | sed 's/-//g') && \
cat <<EOF >> /boot/grub/grub-pre.cfg
set crypto_uuid=$CRYPTOID
cryptomount -u \$crypto_uuid
set prefix=(crypto0)/@boot/grub
insmod normal
normal
EOF

grub-mkimage -p /boot/grub -O x86_64-efi -c /boot/grub/grub-pre.cfg -o /tmp/grubx64.efi $GRUB_MODS && install -v /tmp/grubx64.efi /efi/EFI/VOID/grubx64.efi
exit

Wrapping it up...

## Set start up services
xchroot /mnt ln -sf /etc/sv/dbus /etc/runit/runsvdir/default && \
xchroot /mnt ln -sf /etc/sv/acpid /etc/runit/runsvdir/default && \
xchroot /mnt ln -sf /etc/sv/elogind /etc/runit/runsvdir/default && \
xchroot /mnt ln -sf /etc/sv/crond /etc/runit/runsvdir/default && \
xchroot /mnt ln -sf /etc/sv/socklog-unix /etc/runit/runsvdir/default && \
xchroot /mnt ln -sf /etc/sv/nanoklogd /etc/runit/runsvdir/default && \
xchroot /mnt ln -sf /etc/sv/avahi-daemon  /etc/runit/runsvdir/default && \
xchroot /mnt ln -sf /etc/sv/iwd  /etc/runit/runsvdir/default && \
xchroot /mnt ln -sf /etc/sv/NetworkManager  /etc/runit/runsvdir/default

swapoff -a && \
umount -R /mnt && \
echo "Reboot and enjoy... your base system is complete. =)"

Post-configure ... after rebooting

These are things I've done after getting the system up and running on the network

Wifi (getting online)

  1. Turn off the wifi powersave. This is very specific to the wifi card in this laptop where it will degrade over time.
echo 'ACTION=="add", SUBSYSTEM=="net", KERNEL=="wl*", RUN+="/usr/bin/iw dev $name set power_save off"' > /lib/udev/rules.d/81-wifi-powersave.rules
  1. Tweak the wifi card from slowing down after resume. 3
# Create the following file with the contents below chmod +x to make it executable

cat <<EOF >> /etc/zzz.d/resume/ath11k_pci.sh
#!/bin/sh

modprobe -r ath11k_pci
modprobe ath11k_pci
EOF

chmod +x /etc/zzz.d/resume/ath11k_pci.sh
  1. Let's also setup Cloudflare to be our global DNS
cat <<EOF >> /etc/NetworkManager/conf.d/dns-servers.conf
[global-dns-domain-*]
servers=1.1.1.1,1.0.0.1,2606:4700:4700::1111,2606:4700:4700::1001
EOF
  1. Connect to the wifi network...
nmcli device wifi connect <SSID_or_BSSID> password <password>
  1. Get a better mirror...
xbps-install xmirror
xmirror # Select a better mirror...

SSH (Dropbear)

I will use ssh for now until I can be more productive directly on the machine but it is easier to be logged in via ssh.

  1. Disable sshd and be sure it is off
touch /etc/sv/sshd/down
sv stop sshd
  1. Setup the dropbear service options & enable it
touch /etc/sv/dropbear/down
echo 'OPTS=" -F -w -m -R "' > /etc/sv/dropbear/conf
ln -sf /etc/sv/dropbear /etc/runit/runsvdir/default
  1. Start it
sv start dropbear

Power Management (tweaks & tools)

  1. I like to use auto-cpufreq to manage the CPU power
git clone https://github.com/AdnanHodzic/auto-cpufreq.git
cd auto-cpufreq && sudo ./auto-cpufreq-installer
sudo auto-cpufreq --install

# I also modified my grub to have the following...
GRUB_CMDLINE_LINUX_DEFAULT="... amd_pstate.shared_mem=1 ..."
sudo update-grub

# reboot
  1. I also need to set battery thresholds to maximize battery life
xbps-install tpacpi-bat
reboot

# Create a file that will set the thresholds...
cat <<EOF >> /usr/sbin/set_battery_thresholds
#!/bin/sh

/usr/bin/tpacpi-bat -s ST 0 40
/usr/bin/tpacpi-bat -s SP 0 80
EOF

chmod +x /usr/sbin/set_battery_thresholds

# Modify the /etc/acpi/handler.sh script to set the battery threshold...

#... other ACPI stuff
battery)
  case "$2" in
    BAT0)
      case "$4" in
        00000000)
        ;;
        00000001)
        /usr/sbin/set_battery_thresholds
        ;;
#... more ACPI stuff

Xorg (X11)

  1. Setup the base configuration and copy it to appropriate folder
sudo Xorg :0 -configure
mv /root/xorg.conf/new /etc/X11/xorg.conf
  1. Setup a local copy of xinit configs
cp /etc/X11/xinit/xinitrc ~/.xinitrc
cp /etc/X11/xinit/xserverrc ~/.xserverrc

sed -i '/^exec \/usr\/bin\/X/ s/$/ -keeptty/' ~/.xserverrc
  1. Run X rootless
echo 'needs_root_rights = no' > /etc/X11/Xwrapper.config

Footnotes

  1. https://download.lenovo.com/pccbbs/mobiles_pdf/z13_z16_gen1_hmm_en.pdf

  2. https://forum.endeavouros.com/t/dracut-grub-speed-up-boot-by-specifying-a-boot-device-and-kernel-command-line/37343

  3. https://forums.lenovo.com/t5/Other-Linux-Discussions/QCNFA765-Linux-ath11k-wifi-crippled-high-latency-packet-loss-frequent-disassociations-T14s-AMD/m-p/5252399

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment