Improving boot times on the Framework 13 (<13 seconds!) and general Arch setup guide

hi folks! Finally got my 13/7640u in the new year, and I’ve been fiddling building Arch (btw) from the ground up. Figured that I’d share what I’ve done to get boot times down to 11-13 seconds, and give a good semi-concrete guide to set Arch up. Note that these instructions may become less relevant over time, though I’ll do my best to keep it updated.

Might not work identically on your machine (although it’ll most likely also work on the 12 or 16), and I’m definitely not an expert, so maybe don’t follow this guide unless you have the time and mental capacity to get yourself out of a broken system, k?

You can do this from an existing install, but I strongly recommend starting from scratch for ease of maintenance. This will also make dualbooting more challenging (instead of having a menu like grub or systemd-boot, you’ll have to select an EFI entry in the BIOS) but it has the advantage of hiding Microsoft’s heinous antics unless they find another way to screw with it. Before you start, run systemd-analyze and check how you’re doing at the moment!

The firmware is one place we can’t really improve, taking 6 seconds. Having secure boot off will improve it slightly, and I personally don’t use it, though that part is up to you. I also have a slower NVME than most, which might skew times by a few hundred milliseconds. Interestingly, boot time improves by 1-2 seconds when I remove all four of my expansion cards (2xA, 1xC, 1xHDMI), though I guarantee it takes longer than 2 seconds for you to do that, so… only useful if you’re using the machine headless. If anyone has other tips for speeding up this part of the process, let me know!!

Our biggest gain is going to be replacing a traditional bootloader with an EFI boot stub, saving (in my experience) 5 to 10 seconds. When you start the system, the bootloader is the first thing run by the EFI, picking a kernel and kickstarting everything else (among other things). Typically, you’d use grub or systemd-boot (or windows boot manager), which also allow passing kernel arguments or choosing which system to use. However, the UEFI standard was designed to support running the kernel directly from a single executable, allowing us to directly start the system, skipping loading more software.

Next, we’ll use a UKI (Universal Kernel Image). Normally, the bootloader reads configuration files, loads the kernel image, an initramfs (temporary filesystem with some things the kernel uses), microcode (processor firmware), and then finally transfers the control to your kernel to manage hardware. What we’re doing here is putting the kernel in control from the start, letting it unpack initramfs and microcode itself, bringing our time down to 1 second until kernel start(!).

RMS jumpscare!!

I’d just like to interject for a moment. What you’re refering to as Linux, is in fact, GNU/Linux, or as I’ve recently taken to calling it, GNU plus Linux. Linux is not an operating system unto itself, but rather another free component of a fully functioning GNU system made useful by the GNU corelibs, shell utilities and vital system components comprising a full OS as defined by POSIX. There really is a Linux, and these people are using it, but it is just a part of the system they use. Linux is the kernel: the program in the system that allocates the machine’s resources to the other programs that you run. The kernel is an essential part of an operating system, but useless by itself; it can only function in the context of a complete operating system. Linux is normally used in combination with the GNU operating system: the whole system is basically GNU with Linux added, or GNU/Linux. All the so-called Linux distributions are really distributions of GNU/Linux!

As Stallman helpfully details, Torvalds created the Linux kernel, and its job is to manage interactions between your software and your hardware. We can improve boot times further by compiling our own kernel, but this is specific to each person, so I won’t be covering it here. The default Arch kernel is already pretty well optimized anyways.

Finally, once the kernel has started in about 4 seconds, you’re in userspace: this is where systemd starts its own apps, and this varies depending on your system’s setup. I have it down to 2.3 seconds, but you may have more or less depending what you need to start, especially if you want to use a full desktop environment (KDE/Gnome). I use Hyprland, but I get if you don’t have the patience to learn that lmao

TLDR: 4-6 seconds we can’t get rid of in the firmware, 1 second loading the kernel via an EFI boot stub, 4 seconds loading the kernel as a UKI, 3 seconds loading userspace, 4 hours figuring out why your audio isn’t working = 13 seconds!

just give me the damn guide already man

(Skip to Step 10 if you already know how to set Arch up)
Okay, SO. I’m assuming you’re somewhat familiar with Linux already. If you’re new, RTFM; I strongly recommend not using archinstall for your first time.

  1. You’ll need a USB key to boot off. It’ll be erased, so back up any data on it. I like Ventoy (dot net); add the Arch live image.

  2. If you already have an OS on your laptop, I recommend you back up your data.

  3. Partition your disk. I like getting the gparted live ISO and using that for simplicity. You’ll need:

    • An EFI partition (ESP) of >=1GiB. If you already have one, USE THAT ONE! Just resize it. You’ll have to move other partitions to make it fit.
    • A swap partition. 4-8GiB is suitable normally, but if you want to use hibernation, you’ll need it to be 1.5 times the amount of RAM your system has.
    • Your root (main) partition. I like using ext4 but up to you… if you already have other partitions, it’s your choice as to whether you put it on the left or the right.
  4. Format your partitions, then boot the Arch install media. Follow the Arch install guide to set the keyboard layout, connect to the Internet, and set the clock.
    Mount your disks:
    lsblk (find your root partition)
    mkdir -p /mnt/boot/efi (set up where your partitions will mount to)
    mount /dev/nvme0n1pX /mnt (where X is the partition number of your new root)
    mount /dev/nvme0n1pX /mnt/boot/efi (where X is your ESP)
    mkswap /dev/nvme0n1pX (where X is your swap partition)
    swapon /dev/nvme0n1pX (ditto)

  5. Set up your pacman mirrors by editing /etc/pacman.d/mirrorlist.
    I like to use reflector.

  6. Install needed packages:
    pacstrap -K /mnt package package package etc

    • Essential packages: base base-devel linux linux-firmware efibootmgr networkmanager vim git man-db man-pages noto-fonts wl-clipboard
    • Framework: fwupd power-profiles-daemon bluez bluez-utils fprintd brightnessctl
    • Manufacturer specific drivers:
      • For AMD Frameworks: amd-ucode mesa lib32-mesa vulkan-radeon lib32-vulkan-radeon libva-mesa-driver lib32-libva-mesa-driver
      • Intel: intel-ucode mesa lib32-mesa vulkan-intel lib32-vulkan-intel intel-media-driver
    • Audio: pipewire pipewire-alsa pipewire-pulse pipewire-jack wireplumber alsa-utils pavucontrol
    • Utilities:
      • rofi-wayland: app launcher
      • kitty or alacritty: terminal
      • vivaldi: really awesome chromium browser
      • nnn, feh: terminal file browser and image viewer
      • zsh zsh-completions my favourite shell
      • ly: Super cool (and fast!!) display manager/login screen
      • dolphin or thunar - file managers
    • Hyprland stuff: hyprland xdg-desktop-portal-hyprland xdg-desktop-portal-gtk qt5-wayland qt6-wayland polkit-kde-agent grim slurp waybar playerctl dunst
    • KDE: plasma, Gnome: gnome, gnome-circle (optional)
  7. Generate the fstab (inspect it after to make sure it’s good):
    genfstab -U /mnt >> /mnt/etc/fstab

  8. chroot into the new system (arch-chroot /mnt), then set your time, locale, root password, and hostname as per the Arch wiki. After this, if the system is shut off without finishing, don’t panic; go back and remount the partitions, then arch-chroot back in.

  9. Add a user account:
    useradd -mG wheel username
    passwd username
    EDITOR=vim visudo
    That last command will open Vim to edit the suoders file: look for a line like Uncomment to let members of group wheel execute any action and… go figure… uncomment it.
    Basics of Vim:

  • Use arrow keys to navigate around
  • Press a to switch to append mode and type
  • To save, hit escape then type :w and hit enter, or to write and quit :wq
  • To quit, type :qa (or :qa! if it complains)
  1. Okay here’s where the crazy new stuff starts. Get your partition UUIDs and copy them down exactly (where X is your swap, and Y is your root):
    lsblk (to get which partition is which)
    blkid | grep -E '(nvme0n1pX|nvme0n1pY)'
    Open vim /etc/mkinitcpio.conf and comment out whatever HOOKS= line is already there, then add a new line:
    HOOKS=(base systemd autodetect microcode modconf kms keyboard sd-vconsole block filesystems fsck).
    If you want to hide console output during boot, sudo pacman -S plymouth and add plymouth to the end of the HOOKS line.

  2. Edit vim /etc/mkinitcpio.d/linux.preset, then delete everything (esc and type ggdG). Type this in:

ALL_config="/etc/mkinitcpio.conf"
ALL_kver="/boot/vmlinuz-linux"

PRESETS=('default')

default_uki="/boot/efi/EFI/Linux/arch-linux.efi"
default_options="--splash /usr/share/systemd/bootctl/splash-arch.bmp"

If you’d like to have your own splash image, you can pick the path of any .bmp file as long as it’s equal or less than your display’s resolution. I like putting it in the same directory for clarity. You’ll have to rebuild the image to change it (step 13).

  1. Run:
    mkdir -p /etc/kernel
    echo root=UUID=(your root uuid) resume=UUID=(swap uuid) rw quiet splash loglevel=3 mem_sleep_default=deep > /etc/kernel/cmdline
    If you ever need to add kernel parameters for whatever reason, add them to this file and rebuild your UKI.

  2. Build the UKI. Run mkinitcpio -p linux (you’ll need to do this (with sudo) every time you make modifications to the above

  3. Create your EFI boot menu option, so you don’t have to manually select the EFI image: (where X is your ESP number)
    efibootmgr --create --disk /dev/nvme0n1 --part X --label "Arch" --loader '\EFI\Linux\arch-linux.efi' --unicode (you can choose whichever label you like).
    Type efibootmgr and make sure your Arch install is the first priority; use efibootmgr --bootorder 0000,0001,0002 to set a boot order (replace with the actual numbers of things).

  4. Every time the linux package gets upgraded, you’ll want your system to rebuild the image:
    touch /etc/pacman.d/hooks/90-mkinitcpio-install.hook
    vim /etc/pacman.d/hooks/90-mkinitcpio-install.hook
    and type in

[Trigger]
Type = Package
Operation = Install
Operation = Upgrade
Target = linux

[Action]
Description = Rebuilding UKI...
When = PostTransaction
Exec = /usr/bin/mkinitcpio -p linux
  1. You should have a functional system! Finally:
    systemctl enable NetworkManager bluetooth fwupd-refresh.timer
    exit
    umount -R /mnt
    reboot
    and pray

  2. You can now set up your system how you like! Some next steps:

  • Configure whichever DE/WM you chose
  • Set up ly if you chose to use it! Highly recommend. (systemctl enable ly@tty2.service)
  • basically anything else lmao it’s your computer
  • If you want to see how fast your system is now: systemd-analyze

aaand that’s it! did I get the record for the longest first post? No? Oh well. I’ll do my best to keep this updated, but please let me know if any part needs attention. I hope some people can draw from this; people breaking away from Microsoft is important to me and although this maybe isn’t the best starting place anything helps hm

thanks guys! my laptop is awesome :victory_hand:
~qwik

Thank you for the nice writeup!

I will definitely check out some of your boot time improvments.

Do you have some systemd-analyze printouts from a standard install vs your improved versions?

I’m currently using arch with systemd-boot and no secureboot. But also nothing specifically done to improve bootimes. I’m on a 7840 system though. Still already pretty good:

image

Best,
Frostregen

1 Like

I haven’t tried installing Arch tomfoolery-less on this laptop… my desktop (5600 + 6650XT) takes a lot longer, but this install runs KDE Plasma and is also the first time I’d ever used Arch (or seriously used Linux, for that matter), so it’s terribly misconfigured. I’ve been meaning to get around to reinstalling:
Startup finished in 11.519s (firmware) + 6.539s (loader) + 4.048s (kernel) + 5.673s (initrd) + 11.499s (userspace) = 39.280s

Obviously it’s diminishing returns, though it looks like you’re already running pretty lean (what WM/DE you on?). I’d not actually tried systemd-boot before, looks like it’s way faster than grub, and yea the better CPU probably rigs this a bit

The laptop:
Startup finished in 4.954s (firmware) + 656ms (loader) + 577ms (kernel) + 2.887s (initrd) + 2.498s (userspace) = 11.573s
That’s with the expansion cards taken out; don’t have the laptop on me at the moment, but having them in slows the firmware down by 1 to 1.5 seconds.

Wonder if secure boot has any effect on it. I’d expect it slows it down slightly?
too lazy to screw with it though lmao

If you do try to set this up on an existing install, make sure you have a live disk ready; pacman might be a little silly picking the right kernel. I will also note that picking between systemd and busybox when setting up mkinitcpio’s hooks (step 10) didn’t seem to have a performance difference to me, but it might be something to test on the better performing system…