Manual setup

drivers, networking, X11 and Wayland, by hand

Read this first

A base install boots to a console and nothing else. There is no display manager, no desktop, no driver auto-installer and no daemon quietly fixing things behind you. Everything below is a step you take deliberately, in order.

The order matters more than any single command here. A device whose driver was never loaded does not exist as far as the rest of the system is concerned - it has no interface name, no /dev node, and every tool that looks for it correctly reports that it is not there. Most "my wifi does not work" and "X will not start" reports are really "the driver never loaded", one layer further down than where the error appeared.

1. Firmware and drivers

Do this before touching networking or graphics.

Most wireless cards, and every modern GPU, need a firmware blob the kernel loads into the device at probe time. The kernel module alone is not enough: without the blob the driver loads, fails to bring the hardware up, and logs the failure to dmesg where nothing else looks.

scraps add linux-firmware        # ~390 MB installed - Intel/Atheros/Realtek wifi, AMD/Intel GPU
scraps add wireless-regdb        # regulatory database, see "regulatory domain" below

Device manager and coldplug

eudev is the device manager. Its daemon, udevd, reacts to new uevents - a device plugged in while the system is running. Hardware that was already present at boot announced itself before any daemon was listening, so those events have to be replayed once at startup. That replay is the coldplug pass, and it is what actually loads drivers for the hardware already in the machine.

scraps add eudev

# both services want to be enabled: the daemon, and the coldplug pass
: > /etc/scraplinux/services/udevd
: > /etc/scraplinux/services/udev-trigger

# regenerate the service files for whichever init is running
scraplinux-init-setup s66        # or: busybox, openrc, runit, dinit, nitro

Verify all three of these before moving on. If udevadm does not run, nothing below it can work:

udevadm --version                # must print a version
lsmod | grep -i iwlwifi          # your driver, loaded
ip link                          # your interface, present

If ip link shows only lo, no driver is loaded. Load one by hand and read why it did or did not take:

doas modprobe iwlwifi            # or ath9k, rtw88, mt76 - whatever the card is
dmesg | tail -40                 # firmware loaded? rejected? missing?
lspci -nnk | grep -iA3 network   # what the card actually is, and which driver claims it

A module that inserts cleanly but still produces no interface is almost always a missing firmware blob - dmesg names the file it wanted.

2. Networking

Nothing here works until ip link shows the interface. If it does not, go back to the previous section.

Wired

ip link set eth0 up
udhcpc -i eth0                   # busybox DHCP client

rc.d/network does exactly this on every boot, picking the first non-loopback, non-wireless interface it finds.

Wireless, the short way

wifi-connect                     # scan, pick a network, enter the passphrase
wifi-connect <ssid> <psk>        # no prompts
wifi-connect scan

On success it writes the SSID, passphrase and interface to /etc/scraplinux/network.conf, and rc.d/wifi reconnects from that file on every subsequent boot.

Wireless, by hand

The same thing wifi-connect does, one step at a time:

iw dev                           # confirm the wireless interface exists
ip link set wlan0 up

wpa_passphrase '<ssid>' '<psk>' > /etc/wpa_supplicant.conf
wpa_supplicant -B -i wlan0 -c /etc/wpa_supplicant.conf
udhcpc -i wlan0

Regulatory domain

With no regulatory database the kernel stays in world domain 00, where most 5 GHz channels are receive-only. The access point appears in a scan and the card is then forbidden to transmit to it - which looks exactly like a wrong passphrase.

scraps add wireless-regdb
WIFI_COUNTRY=US wifi-connect      # set a country code for one run

3. Seat access

Both X11 and Wayland need permission to open the GPU and the input devices. On systemd distributions logind hands that out; here it is seatd (small, recommended) or elogind (the logind fork, if something you run expects its D-Bus interface).

scraps add seatd
: > /etc/scraplinux/services/seatd
scraplinux-init-setup s66

# your user needs to be in these groups
doas usermod -aG seat,video,input <user>

Log out and back in afterwards - group membership is read at login, so a shell you were already sitting in will not have it.

4. X11

scraps add xorg-server xorg-xinit xf86-input-libinput mesa libglvnd
scraps add ttf-dejavu             # X with no fonts starts and looks broken

xf86-input-libinput is not optional. Without it the X server starts, draws, and has no keyboard or mouse driver at all - a running session you cannot type into, which reads as a freeze.

Pick a window manager and tell startx to run it. The last line of .xinitrc is the session: when it exits, X exits.

scraps add dwm dmenu st           # or: openbox, icewm, xfwm4

printf '#!/bin/sh\nexec dwm\n' > ~/.xinitrc
chmod +x ~/.xinitrc
startx

If X dies immediately, the reason is in the log, not on the console:

grep -E '\(EE\)|\(WW\)' /var/log/Xorg.0.log

5. Wayland

A Wayland compositor is the display server and the window manager at once, so there is no startx equivalent - you run the compositor directly.

scraps add wayland
scraps add dwl                    # or: labwc, niri, sway, swayfx, hyprland, i3wl
scraps add foot fuzzel waybar mako    # terminal, launcher, bar, notifications

XDG_RUNTIME_DIR

Wayland requires XDG_RUNTIME_DIR - it is where the compositor puts its socket. On systemd distributions logind creates it at login. Here, if you are not running elogind, nothing does, and every compositor exits immediately with a message about the runtime directory. Set it before launching:

export XDG_RUNTIME_DIR=/run/user/$(id -u)
mkdir -p "$XDG_RUNTIME_DIR"
chmod 700 "$XDG_RUNTIME_DIR"

Put those three lines in your shell profile rather than retyping them. Then start the compositor:

dwl                                       # bare
dbus-run-session dwl                      # with a session bus
dbus-run-session dwl -s ~/.config/dwl/autostart.sh   # and a startup script

Wrap it in dbus-run-session if you want a notification daemon, a system tray, or anything else that talks over the session bus - without one, mako and tray applets start and then find nothing to talk to.

i3wl is a prebuilt option here: a dwl fork with i3-style tiling, a tray and a status bar, shipped with its own launcher.

scraps add i3wl
i3wl                              # wraps dbus-run-session itself

Checklist

In order. Each step is only worth attempting once the one above it is true.

udevadm --versiondevice manager works at all
lsmodthe driver for your hardware is loaded
ip linkthe network interface exists
ping -c1 1.1.1.1routing and DHCP work
ls /dev/drithe GPU node exists
echo $XDG_RUNTIME_DIRset, for Wayland
More: scraplinux linux docs · install · configuration · packages · kernels & generations · networking, desktops & init · troubleshooting & reference