top of page

Installing NeXTSTEP 3.3 (SPARC) in QEMU on Linux

  • Writer: Alex Gorouvein
    Alex Gorouvein
  • 1 day ago
  • 6 min read

Updated: 1 day ago

A complete guide to installing, stabilizing, and configuring NeXTSTEP 3.3 for SPARC under qemu-system-sparc, emulating a Sun SPARCstation 5 (-M SS-5). Based on a real troubleshooting session on Garuda Linux (Arch-based), but the fixes here apply to any modern Linux distro with a recent QEMU.

NeXTSTEP 3.3 SPARC in QEMU


1. The core problem: modern QEMU is broken for this combination


If you're on QEMU 8.x, 9.x, or later, stop before you start — recent qemu-system-sparc releases have open, unresolved regressions in the sun4m/SS-5 ESP-SCSI and DMA emulation that cause:
  • Freezes during console-phase file copy while installing
  • Freezes during the GUI package-extraction phase of install
  • Graphical corruption or hangs right at the Window Server handoff

These are tracked upstream as QEMU issue #2620 and #2674, both still open. No combination of flags reliably fixes this on affected versions — the fix is to use an older, known-good QEMU: 7.2.x.
Even on 7.2.x, a residual timing-sensitive race in the ESP/DMA emulation can still occasionally cause a hang during large file copies. It's much rarer, but not impossible — see the qcow2/snapshot strategy in Section 7, which turns a rare hang from a disaster into a 30-second inconvenience.
Where to get the files


Why distrobox instead of just downgrading your system QEMU

If you have other working QEMU-based emulation setups on your machine (in this session's case: HP-UX, AIX, and Solaris 8), you don't want to downgrade your system's QEMU package and risk breaking those. Building QEMU 7.2.x from source against a modern host toolchain is also surprisingly painful — in this session it failed three separate times against Garuda's up-to-date compiler and libraries (a libnfs API mismatch, an xkbcommon/xkeyboard-config keymap generation failure, and would likely have hit more).
Distrobox solves both problems at once: it creates a lightweight container running an older Linux distribution (Debian 12 "Bookworm," which ships QEMU 7.2 as a normal package), while transparently sharing your home directory, display server, and other host resources. You get a genuinely isolated, version-appropriate QEMU with a two-minute apt install, your host's QEMU and other VMs are completely untouched, and it's fully removable with one command if you ever want it gone.

2. Set up the distrobox environment


sudo pacman -S distrobox podman        # Arch/Garuda; use your distro's package manager
distrobox create --name qemu-sparc-old --image debian:bookworm
distrobox enter qemu-sparc-old
sudo apt update
sudo apt install qemu-system-sparc socat
qemu-system-sparc --version            # should report 7.2.x

Your home directory is automatically shared into the container, so disk images and ISOs referenced by their normal host paths just work from inside it.
If fish shell shows errors about starship or eza when entering the container, ignore them — they're just your host's shell config referencing tools not installed in the container. Harmless. Use command ls or switch to bash if it bothers you.


3. Create the disk image and run the base install


Create the virtual disk as qcow2 from the start — no reason to install to raw and convert afterward:
qemu-img create -f qcow2 nextstep33_sparc.qcow2 2G

Then run this from inside the distrobox container:
taskset -c 0 qemu-system-sparc \
  -M SS-5 \
  -m 64 \
  -bios ss5.bin \
  -rtc base=utc,clock=host \
  -drive file=nextstep33_sparc.qcow2,format=qcow2,bus=0,unit=3,media=disk,cache=writethrough \
  -drive file=nextstep33_risc.iso,format=raw,bus=0,unit=6,media=cdrom,readonly=on,cache=writethrough \
  -net nic,model=lance -net user \
  -display default \
  -g 1024x768x8

Key details, each one earned the hard way:
Flag
Why it matters
-taskset -c 0
Pins QEMU to a single host core. Works around a real race condition in QEMU's disk I/O emulation on multi-core hosts that causes hangs. Not optional.
-g 1024x768x8
NeXTSTEP's SPARC kernel panics in 24-bit framebuffer mode. Stay at 8-bit.
-bus=0,unit=3 (disk) / unit=6 (CD-ROM)
Matches real Sun SCSI target conventions (internal disk at target 3, CD-ROM at target 6).
-rtc base=utc,clock=host
Ties guest timer interrupts to real wall-clock time; smooths out some of the same timing-sensitive races.

When OpenBoot fails to boot from the network (it's a default boot-device in the ss5.bin) and drops to the `ok` prompt, just type boot cdrom and press Enter, then press Enter again at the NeXTSTEP boot: prompt.

4. Fix #1: the /etc/fstab device mismatch (single-user drop after install)


Symptom: On a successful install, the first reboot doesn't hang — it simply drops you into single-user mode automatically instead of continuing to a normal boot.
Cause: At boot, fsck tries to check /dev/rsd0a (the phantom, never-ready device) instead of /dev/rsd1a (your actual disk), fails, and drops you to that single-user shell.

Fix, from that shell, in this order:
mount -o remount,rw /dev/sd1a /
vi /etc/fstab

Inside /etc/fstab, change the one line from:
/dev/sd0a / 4.3 rw,noquota,noauto 0 1

to:
/dev/sd1a / 4.3 rw,noquota,noauto 0 1

Keep noauto and every other option exactly as-is — only the device name changes. Save and exit, then:
fsck -y /dev/rsd1a
sync
sync
reboot


5. Fix #2: Networking (QEMU user-mode NAT)


QEMU's default -net user networking always uses this subnet:

Setting
Value
Guest IP
10.0.2.15
Netmask
255.255.255.0
Gateway/Router
10.0.2.2
DNS proxy
10.0.2.3

`Configure.app` and `SimpleNetworkStarter.app` are dead ends for this — they either don't do what their names suggest or hang entirely (see Section 6 for why). The reliable method is editing /etc/hostconfig directly:
HOSTNAME=nextsparc
INETADDR=10.0.2.15
ROUTER=10.0.2.2
IPNETMASK=255.255.255.0
IPBROADCAST=10.0.2.255
NETMASTER=-YES-
YPDOMAIN=-NO-
TIME=-AUTOMATIC-
DOMAIN=-AUTOMATIC-

Double-check `IPNETMASK` and `IPBROADCAST` aren't swapped or mistyped. A wrong netmask here (e.g. accidentally using the broadcast address as the netmask) breaks the kernel's subnet calculation for en0, which then makes the default route add fail with "Network is unreachable," which can cascade into NetInfo/lookupd startup hangs too. If networking seems broken after a hostconfig edit, cat /etc/hostconfig and read every line back carefully before assuming something else is wrong.

Keep NETMASTER=-YES- — it tells the boot scripts this machine is the authoritative master of its own local NetInfo domain (not dependent on syncing from another machine), which is correct for a standalone install. It's unrelated to the broadcast-search issue in Section 6.
Create /etc/resolv.conf (via Edit.app, saved to exactly that path):
domain localdomain
nameserver 10.0.2.3

Use 10.0.2.3 (QEMU's own built-in DNS proxy), not your host's real router IP. A real home router's DNS proxy frequently mishandles queries that arrive already NAT-translated through QEMU's slirp networking, returning bogus NXDOMAIN responses instead of forwarding them — 10.0.2.3 is specifically built for this and avoids that entirely.
Test:
/etc/ping 10.0.2.2      # gateway
/etc/ping 10.0.2.3      # DNS proxy

If DNS still doesn't resolve names (ping/nslookup say "unknown host")

NeXTSTEP's lookupd has its own search order for name resolution, separate from /etc/resolv.conf existing at all. If DNS isn't in that order, hostnames will never resolve even with a perfectly correct resolv.conf. Add it via NetInfo:
niutil -read . /locations
niutil -read . /locations/lookupd
niutil -createprop . /locations/lookupd LookupOrder "DNS NetInfo"
Watch your spacing carefullyniutil takes the domain (.) and the path (/locations/lookupd) as two separate arguments. Running them together with no space (./locations/lookupd) is a very easy typo to make and causes a confusing can't connect to server for domain error that has nothing to do with the actual command you're trying to run. Reboot after fixing this. Or better yet, do the next fix and then reboot.

6. Fix #3: NetInfo "searching for parent" boot hang


Symptom: Boot displays Still searching for parent network administration (NetInfo) server and waits indefinitely (or until you press c to continue without network user accounts). GUI tools like NetInfoManager.app and SimpleNetworkStarter.app hang when launched — not because they're broken, but because they're waiting on the exact same stuck lookup.

Cause: The local NetInfo domain's /machines/broadcasthost record has a serves property that tells netinfod to broadcast-search for a parent domain server. Under QEMU's NAT networking, that broadcast can never succeed, so it waits forever every single boot.

Fix (surgical — doesn't touch your users, hostname, or any other NetInfo data):

  1. Open /NextAdmin/NetInfoManager.app
  2. Navigate to /machines/broadcasthost
  3. Double click on broadcasthost
  4. Select the serves property → Edit menu → Delete.
  5. Directory menu → Save.
  6. Reboot. The message should be gone for good.

Do not try to fix this by wiping and replacing /etc/netinfo wholesale with a template directory — it's a much blunter approach that risks corruption if done while daemons are live (it caused a new, different hang in this session), and it's unnecessary when the actual fix is one property on one record.


7. Protect yourself with qcow2 snapshots


Since the underlying QEMU race condition (Section 1) can still occasionally resurface even on 7.2.x, and a forced kill mid-write can corrupt a disk image beyond repair, this is exactly why Section 3 has you create the disk as qcow2 from the start rather than raw — qcow2 supports snapshots, raw doesn't. Take a snapshot after every major, hard-won milestone:
qemu-img snapshot -c clean-install nextstep33_sparc.qcow2
qemu-img snapshot -c clean-network nextstep33_sparc.qcow2
qemu-img snapshot -c clean-devtools nextstep33_sparc.qcow2

(always with QEMU not running against the file)
Before any risky operation — a large file copy, a system patch, hand-editing a shared library — take a throwaway snapshot:
qemu-img snapshot -c pre-copy nextstep33_sparc.qcow2

If it hangs, force-quit and revert in seconds instead of losing hours of setup:
qemu-img snapshot -a pre-copy nextstep33_sparc.qcow2

List existing snapshots anytime with:
qemu-img snapshot -l nextstep33_sparc.qcow2


Summary checklist


  • ☐ Confirm QEMU version; if 8.x+, set up distrobox with Debian Bookworm's QEMU 7.2
  • ☐ Install with taskset -c 0, 8-bit framebuffer, disk on unit 3 / CD on unit 6
  • ☐ Fix /etc/fstab (sd0a → sd1a) after install (single-user drop, not a hang)
  • ☐ Configure /etc/hostconfig and /etc/resolv.conf for QEMU's NAT networking
  • ☐ Add DNS to lookupd's search order via niutil if names don't resolve
  • ☐ Delete the serves property on /machines/broadcasthost if boot hangs searching for a NetInfo parent
  • ☐ Use qcow2 and snapshot before anything risky

 
 
 

Comments


Richmond Hill, Ontario, Canada

  • instagram
  • facebook

©2026 by hifialex.com. Proudly created with Wix.com

bottom of page