Steam Link Repurposing for 3D Printing (Debian Install + WiFi Setup + Octoprint Install)

by crackd engie in Circuits > Linux

77 Views, 0 Favorites, 0 Comments

Steam Link Repurposing for 3D Printing (Debian Install + WiFi Setup + Octoprint Install)

stlink.jpg

Have you bought a Steam Link a looong time ago and is it now collecting dust bunnies instead of actually being used? Great! Then you'll love what's next. I'll be honest with you from the very beginning, this thing ain't got much juice in it but it's absolutely perfect if you do have that ONE specific thing that is a pain in the a-hole and you, just like me, are not in the mood to get scalped for a Raspberry Pi Zero or you almost threw away the steam link. (you can find the steam link on ebay for around 10-20$, probably even cheaper if you go thrifting)

Supplies

ibFDTM5bJwXo4rczxSWAAF.jpg
  1. Steam Link + the power brick for it.
  2. Any USB thumbdrive (32GB should be more than enough, feel free to experiment tho).
  3. USB C cable that can pass data.

Installing Debian

Screenshot 2026-08-09 102251.png
Screenshot 2026-08-09 101347.png

This whole project builds on top of djmuted/steamlink-debian, which provides the actual Debian image and boot process that gets Linux running on the Steam Link's Marvell SoC in the first place. Go star that repo this guide only covers what to do after you already have Debian booting from a USB stick, namely getting WiFi working. Also, you should get Debian 13 Trixie, fortunately there's this person explaining how to get it up and running, cheers to this person too.

A couple of relevant details from that project's README, worth knowing upfront:

  1. Default login is debian / steamlink, change it immediately with passwd.
  2. HDMI output stops working as soon as the custom kernel boots, so SSH over Ethernet is required for first boot.
  3. Known non-working hardware on this image: NAND driver, DMA controller, video/audio output, suspend/resume/halt/reboot, RTC.
  4. If you get tired of Debian you can also install Arch or yank the usb drive and get your Steam Link back to collecting dust bunnies.



So yeah, just go to the repo, get debian on the usb drive and come back here. As you can see the specs aren't massive but just for reference: CPU-wise this is roughly comparable to a Raspberry Pi Zero/Zero W but with a dual core instead of single core, so it has a bit more headroom for anything that can use two threads.

Getting the WiFi Up

This is why I wanted to write this guide: it's not impossibly hard but it's boring and if you never touched Linux it's not gonna make any sense.


Prerequisites

  1. Debian (12 "bookworm" or 13 "trixie", depending on the image you flashed) already booted on the Steam Link
  2. A working SSH session over an already-active interface (e.g. eth0 via cable)


Procedure

1. Identify available network interfaces

ip a

Look for the WiFi interface: on Marvell SDIO chips it's typically named mlan0.


2. Make sure apt actually works

sudo apt update

If you get errors like Temporary failure resolving 'deb.debian.org' (like I did), the problem is DNS, not the repositories. Check:

cat /etc/resolv.conf

If it's empty or broken, a quick fix:

echo "nameserver 8.8.8.8" | sudo tee /etc/resolv.conf
sudo apt update


3. Install NetworkManager

sudo apt install network-manager


4. Check that WiFi isn't blocked via rfkill

rfkill list

If you see Soft blocked: yes or Hard blocked: yes: (I didn't have this problem but worth checking)

sudo rfkill unblock wifi



5. Make sure NetworkManager is actually managing the WiFi interface

nmcli device status

If mlan0 shows up as unmanaged, edit the config:

sudo nano /etc/NetworkManager/NetworkManager.conf

Make sure it contains:

[ifupdown]
managed=true

Then restart the service:

sudo systemctl restart NetworkManager
nmcli device status

mlan0 should now show as disconnected or available.


6. Connect to the WiFi network

nmcli device wifi list
nmcli device wifi connect "NETWORK_NAME" password "PASSWORD"


7. Verify WiFi access before unplugging Ethernet

An SSH session opened against the eth0 IP address does not automatically migrate to WiFi. Before unplugging the cable:

ip a show mlan0

Note the assigned IP, then from a separate terminal try connecting:

ssh debian@<mlan0-ip>

Only unplug Ethernet once this second connection works.


Troubleshooting encountered along the way

Error: Unable to locate package network-manager


apt update never succeeded, usually due to an underlying DNS issue


Fix: Check /etc/resolv.conf, set a working nameserver

/////////////////////////////////////////////////////////////////////////////

Error: Temporary failure resolving [...]


DNS not configured / not working


Fix: echo "nameserver 8.8.8.8" | sudo tee /etc/resolv.conf

/////////////////////////////////////////////////////////////////////////////

Error: mlan0 shows as unmanaged in nmcli device status


NetworkManager configured to ignore ifupdown-style interfaces


Fix: Set managed=true in NetworkManager.conf

/////////////////////////////////////////////////////////////////////////////

Error: nmcli device wifi list returns nothing


Interface unmanaged, blocked by rfkill, or driver/firmware missing


Fix: Check rfkill list, nmcli device status, dmesg | grep -i mlan

/////////////////////////////////////////////////////////////////////////////

Error: ip: command not found (even with sudo)


The iproute2 package had been removed (rc status in dpkg -l)


Fix: sudo apt install iproute2

/////////////////////////////////////////////////////////////////////////////


Note: NetworkManager vs ifupdown

Debian offers two ways to manage network interfaces: NetworkManager (via nmcli) and the classic ifupdown method (/etc/network/interfaces with wpa-ssid/wpa-psk blocks).

Don't mix both on the same interface. If both try to manage mlan0 at the same time you'll get unstable behavior, like random disconnects, IP addresses disappearing. This guide uses NetworkManager as the primary method because:

  1. it handles reconnection and multiple saved networks more "gracefully".
  2. it avoids storing the password in plaintext in a config file.

If you prefer the ifupdown approach instead, make sure managed=false is set in NetworkManager.conf.


I'm also making an automated script to do all of this that I can't put here (it's a .sh file and it's not supported here) so maybe drop by my Github and, idk, follow me or just take what you need and go on your marry way.

Getting Octoprint to Work

Now this was the part that almost drove me insane. Quick story: I have a 3D printer and everytime I need to print something I have to do all these stupid things because I didn't have a way to remotely connect to it. If you've done 3D printing with budget printers you know exactly what I'm talking about. I also lost the USB micro SD reader that I've been using to transfer files.

This is the hard part of the guide, specifically getting Octoprint to compile with only 500mb of RAM.


1. The core problem: no prebuilt wheels for this architecture

Installing OctoPrint via pip install OctoPrint initially failed with:

Failed to build zeroconf
error: failed-wheel-build-for-install

zeroconf (an OctoPrint dependency) ships C/Cython extensions. Almost no package with compiled extensions has a prebuilt wheel for armv7l + a very recent Python version (Debian 13 ships Python 3.13), so pip falls back to compiling it from source.


2. The build was being OOM-killed

Retrying with more build tools installed still failed, this time with:

died with <Signals.SIGKILL: 9>

A SIGKILL during a build almost always means the Linux out-of-memory (OOM) killer terminated the compiler process. With ~500MB of RAM and no swap compiling zeroconf's C extensions exceeded available memory.

Attempted fix: add a swap file. This failed:

sudo swapon /swapfile
# swapon: /swapfile: swapon failed: Function not implemented

Checking the kernel config confirmed swap support was compiled out entirely:

zcat /proc/config.gz | grep CONFIG_SWAP
# CONFIG_SWAP is not set

This means no swap is possible at all on this kernel, not via a swap file, a swap partition, or zram. The only remaining option was to avoid compiling anything from source.


3. Solution: install precompiled wheels from piwheels

piwheels.org hosts prebuilt wheels for ARM Linux (originally for Raspberry Pi, but the same armv7l architecture applies here). It had a wheel for the exact zeroconf version OctoPrint 1.11.8 requires (zeroconf<0.137,>=0.136.2), built for cp313-armv7l:

source /opt/OctoPrint/venv/bin/activate
pip install "zeroconf==0.136.2" \
--index-url https://www.piwheels.org/simple \
--extra-index-url https://pypi.org/simple

Then install OctoPrint itself the same way, so any other compiled dependencies (like psutil) also come from piwheels instead of being compiled locally:

pip install OctoPrint \
--index-url https://www.piwheels.org/simple \
--extra-index-url https://pypi.org/simple

This completed without errors and installed OctoPrint plus all its dependencies.

Optional: to make piwheels the default extra index for future installs, create ~/.pip/pip.conf:
[global]
extra-index-url=https://www.piwheels.org/simple


After this just plug the USB cable in any port of the Steam Link and in the USB-C port of your printer (or any other USB port, mine has a usb c port).


4. Serial port permission denied

After getting OctoPrint running (octoprint serve), the printer could not be detected. The log showed:

Failed to connect: Port /dev/ttyUSB0 is busy or does not exist

The device existed and was correctly recognized by the kernel (confirmed via dmesg), but:

ls -la /dev/ttyUSB0
# crw-rw---- 1 root dialout 188, 0 ... /dev/ttyUSB0

groups $USER
# debian : debian sudo

The serial port belongs to the dialout group, and the debian user wasn't a member of it so OctoPrint couldn't open the port, and the error message ("busy or does not exist") was misleading; it really meant "permission denied."

Fix:

sudo usermod -a -G dialout debian
sudo reboot # group membership only applies after a fresh login

After rebooting (you have to unplug and plug again the steam link, reboot does not work), groups debian correctly listed dialout, and the printer connected successfully.


5. Running OctoPrint as a systemd service

Initially OctoPrint was started manually with octoprint serve inside an SSH session. During an actual print, the SSH session dropped:

client_loop: send disconnect: Connection reset

Because the process was never detached from the terminal (no systemd, tmux, screen, or nohup), it received a SIGHUP and died with the SSH session which killed the print mid-layer...you can imagine how angry I got.

Fix: run OctoPrint as a systemd service so it's independent of any terminal session (copy-paste all of this in the terminal, it will create the service with all those parameters):

sudo tee /etc/systemd/system/octoprint.service > /dev/null << 'EOF'
[Unit]
Description=OctoPrint
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=debian
ExecStart=/opt/OctoPrint/venv/bin/octoprint serve
Restart=on-failure

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable octoprint
sudo systemctl start octoprint

Check it's running with:

sudo systemctl status octoprint

From this point, closing SSH or rebooting the SteamLink no longer affects OctoPrint, it starts automatically on boot and keeps running in the background.

You're Done!

You can just go to town after this and proceed with the setup of Octoprint as normal, just go to the IP with port 5000 of the steam link and you're good to go. Happy printing!