Feasibility Study

Build plan · revision A

A System 7 workalike that boots on real hardware

A graphical-only Devuan ISO running mlvwm on XLibre, with a System Folder, no user accounts, AppImages in /Applications, and classic Mac software one double-click away. Everything but the last item is a weekend-to-a-fortnight project. The classic-app layer is where the difficulty lives — and the constraint that makes it hard is legal, not technical.

The headline finding: there is a fully redistributable path to running System 7 software, and it does not involve an Apple ROM. See Classic Applications.

Component scoreboard

ComponentVerdictThe actual obstacle
Boot straight to graphicsEasyNone. Standard live-image practice.
mlvwm on XLibreEasy1990s imake and K&R C. XLibre is Xlib-compatible; mlvwm cannot tell it apart from Xorg.
“System Folder” layoutScope callCosmetic version is trivial. A literal one means rebuilding the toolchain.
AppImages in /ApplicationsEasyMenu regeneration, FUSE versions, and write persistence on a live ISO.
A FinderGapmlvwm is only a window manager. No desktop icons, no file manager, no Trash.
No user accountsEasySome applications refuse to run as uid 0. Use a fixed unprivileged user instead.
.sit / .hqx / .bin extractionEasyPreserving resource forks across the Linux filesystem.
Mounting HFS volumesEasyPrefer sandboxed FUSE over the in-kernel drivers — not because they are going away, but because parsing untrusted 1990s media in ring 0 is the wrong place for it.
Running System 7 applicationsHardApple ROMs and Apple system software are not redistributable. One clean-room path is.
Seamless (rootless) windowsResearchNothing off-the-shelf does per-window compositing for 68k Mac software.

1 — Boot Chain

The goal is zero text frames: from firmware handoff to a dithered desktop, the user never sees a console.

FirmwareUEFI / BIOS BootloaderGRUB, hidden menu Kernel + initramfsquiet loglevel=0 squashfs root+ overlay for writes Autologinagetty --autologin XLibre server startx, no display manager mlvwm + Filer + Applications daemon the whole user-visible system No console output at any point — splash covers the gap Devuan base — sysvinit, no systemd anywhere in the chain. Cold boot to desktop: target under 12 seconds on SATA SSD, under 25 from USB 2.0.
Fig. 1 — Boot chain

Decisions

  • Base distribution: Devuan. It inherits Debian's archive, so the entire long tail you need is already packaged — unar, macutils, hfsutils, hfsprogs, qemu — without systemd underneath it. Alpine would give you a ~200 MB ISO, but rebuilding that long tail costs more time than the disk space is worth.
  • Init. sysvinit is the default and the right call here: this system has a fixed, known boot path with no dynamic service topology to manage. runit is a reasonable alternative if you want supervision for the /Applications watcher, but the watcher belongs to the X session, not to init — start it from the session script and the question goes away.
  • Hiding the console. quiet loglevel=0 vt.global_cursor_default=0 on the kernel command line, plus a Plymouth theme, or a bare X splash started from the initramfs if you want to skip Plymouth's dependency weight.
  • No display manager. Autologin on tty1 via agetty --autologin macintosh in /etc/inittab, then startx from the shell profile. No getty on the other VTs, so there is no second console to stumble into.
  • Image builder. live-build is packaged for Devuan and is the shortest path from a package list to a bootable ISO. Devuan's own Refracta tooling is the native alternative and is better at snapshotting a system you have already configured by hand — useful later, once the layout has stopped moving.

Devuan is a good fit beyond the init preference

A System 7 workalike wants a small, legible, static system with a fixed boot path and no service manager negotiating seats and sessions on its behalf. That is Devuan's whole thesis. The one thing to watch: some AppImages expect logind to exist. Devuan ships elogind for exactly this — install it, along with a minimal session dbus, and treat the pair as a compatibility shim for modern applications rather than as part of the system's own architecture.

Bases weighed

BaseVerdictReasoning
Devuan Chosen Debian's archive without systemd. Every tool in this document is already packaged, which is the single largest time saver available.
Tiny Core Steal from it Architecturally the closest thing to this vision that already exists — see below. Rejected as the base on packaging grounds alone.
Alpine Viable, costly A ~200 MB ISO and a clean musl base, but the long tail is thinner and musl breaks a share of prebuilt AppImages outright.
Arch No A rolling base under an immutable, frozen-by-design system is a permanent maintenance tax for no benefit here.

Tiny Core deserves a real answer, not a dismissal

It already implements three things this plan spends effort building. It runs entirely from RAM off a read-only base, which is exactly the immutable System Folder model. It boots straight into X with no display manager and no meaningful account model — the tc user with passwordless sudo is the “no user accounts” goal, already shipped. And its .tcz extension format is squashfs images mounted on demand, which is the same idea as dropping a self-contained bundle into a folder and having it become an application. The philosophical overlap is not partial; it is near-total.

What kills it as the base is the long tail. unar, macutils, hfsutils, hfsfuse, dmg2img, mlvwm, XLibre, Executor, and AMS would all become extensions you build and maintain yourself, on a busybox userland, using an on-demand toolchain. That is the entire dependency surface of this project moved onto your shoulders in exchange for saving a few hundred megabytes. AppImages compound it: they assume a conventional desktop baseline, and Tiny Core is the least conventional baseline available.

The useful synthesis: stay on Devuan and take Tiny Core's architecture anyway — read-only squashfs base, RAM-resident, writable overlay only where the user's own files live. That is already what Fig. 1 and Fig. 2 describe. Revisit Tiny Core as a separate minimal edition once the components are packaged and the porting cost is a known quantity rather than an open one.

Do not run the session as root

“No user accounts” is a user-experience goal, not a uid goal. Chromium-based AppImages and several other applications hard-refuse to start as uid 0. Ship a fixed unprivileged user — call it macintosh, uid 1000, no password, autologin, no account visible anywhere in the interface. Semantically account-free, practically sane. Classic Mac OS had no accounts either; it still ran as an unprivileged system.

2 — The Desktop

What the finished system looks like in normal use: a mounted HFS volume, an AppImage running natively, and a 1994 application in a window beside it.

FileEditViewLabelSpecial
Macintosh HD
Extras.hfs
Trash
System Folder
4 itemsread only
Extensions
Control Panels
Preferences
Startup Items
Applications
6 items4.1 GB available
GIMP.AppImage
Firefox.AppImage
Inkscape
HyperCard
MacPaint
mpv.AppImage
Untitled 1 — MacPaint
1 2 3 4 5 6
  1. 1Menu bar drawn by mlvwm's own bar, not a panel. The mark at the left is a placeholder — see Trade dress.
  2. 2The System Folder, presented read-only. Its contents are bind mounts onto ordinary FHS paths.
  3. 3/Applications holding AppImages and classic applications side by side, indistinguishable to the user.
  4. 4A mounted HFS volume from a period disk image, via userspace FUSE.
  5. 5A 1984 application running under a clean-room Toolbox reimplementation, framed by mlvwm.
  6. 6Trash supplied by the Finder replacement, since mlvwm has none.

The gap nobody mentions: mlvwm is only a window manager

It draws System 7 chrome and manages windows. It has no desktop icons, no file manager, no Trash, and no double-click-to-open. Almost everything in the mockup above that makes it feel like a Macintosh comes from a second program you still have to choose.

ROX-Filer is the closest lightweight fit — pinboard desktop icons, application directories, small dependency footprint. Before committing, look hard at helloSystem: it is a FreeBSD project that has already built most of this vision, and its Qt-based “Filer” is worth borrowing conceptually even though you cannot lift it wholesale onto Linux without work.

3 — The System Folder

Make it a presentation layer, not a filesystem rewrite. The user sees a System Folder; the dynamic linker still sees the paths it was compiled against.

What the user sees What is actually there /System Folder Extensions/ Control Panels/ Preferences/ Fonts/ /Applications /Documents /lib/modules + /usr/lib/xorg/modules /etc + settings front-ends ~/.config /usr/share/fonts /opt/apps (overlay, writable) /home/macintosh/Documents bind, ro bind, rw Untouched underneath: /usr /lib /etc /var /proc /sys /dev — hidden from the Finder, fully intact for the linker and package manager.
Fig. 2 — Presented layout over an unmodified FHS root

Hide the FHS directories from the Finder with a dotfile-style ignore list rather than by moving anything. The Finder replacement decides what is visible; the kernel keeps its own opinion. Nothing on the system needs patching.

Do not do this literally

A real System Folder — with the OS actually living there and no /usr or /lib at all — means a GoboLinux-style rebuild: patched dynamic linker, patched build system, every package rebuilt against new paths, and permanent divergence from the upstream archive. That is a distribution-year of work and it buys nothing the bind-mount presentation does not. Take the cosmetic route and spend the year on the classic-app layer instead.

4 — /Applications and AppImages

Drop a file in a folder; it becomes an application. AppImage is already a single-file bundle, so this maps onto the Macintosh model almost for free.

Drop file/Applications Watcherinotify IN_CLOSE_WRITE Indexer extracts icon + .desktop metadata Menu writer rewrites a marked block ~/.mlvwmrc mlvwm Restartapplication appears in menu Hot path — under a second from drop to menu entry FUSE, both generations ship libfuse2 and fuse3; fall back to --appimage-extract-and-run Write persistence live ISO needs an overlay partition or /Applications is read-only Icon fidelity scale PNG to 32×32 and dither to 1-bit so modern icons match the era Dashed boxes are supporting concerns, not pipeline stages.
Fig. 3 — The /Applications daemon

Notes on implementation

  • Marked block, not full rewrite. Bracket the generated menu with sentinel comments in .mlvwmrc so a user's hand edits outside the block survive regeneration.
  • Restart, not reload. mlvwm predates runtime config reloading; the practical move is Restart, which preserves managed windows.
  • Classic applications land here too. A System 7 application in /Applications gets the same treatment — the indexer just routes it to a different launcher. To the user there is one folder and one gesture.

5 — Archives and Volumes

The whole problem here is the resource fork. Solve it by never letting the payload sit on a Linux filesystem in the first place — go straight from archive to HFS image.

Archive .sit .hqx .bin Extract unar macutils for the crustier ones Both forks intact data + resource, type/creator preserved as AppleDouble Wrap MacBinary single-stream, fork-safe Install hcopy -m → disk.hfs emulator sees a normal volume One gesture in the Finder; five programs underneath Never land here bare ext4 = forks lost Mounting existing media hfsutils for classic HFS · hfsfuse for HFS+ · dmg2img for .dmg · userspace for untrusted images, kernel driver only for volumes the system made itself
Fig. 4 — Archive to mountable volume

Toolchain

ToolHandlesNote
unar / lsarStuffIt 1–5, much of SITX, BinHex, MacBinary, Compact ProThe Unarchiver's command-line tools. Already in the archive, actively maintained, and can emit resource forks rather than discarding them.
macutils.hqx, .bin, MacBinary streamshexbin and macunpack. Ancient, unglamorous, and still the answer for 1980s uploads that unar declines.
hfsutilsClassic HFS read/writehmount, hcopy -m, humount. Userspace, so no kernel exposure. This is how software gets into a volume.
hfsfuseHFS+ / HFSXActively maintained FUSE driver. Read-oriented; treat it as the safe way to browse period media.
dmg2img.dmgConverts to a raw image the above tools can open.

Prefer userspace mounting — for the security reason, not the removal reason

The in-kernel drivers survived. hfs and hfsplus had been orphaned since roughly 2014, and an effort to delete them outright ran through 2025. Maintainers stepped up instead: as of the current tree both are marked Maintained, with three maintainers and a dedicated git tree. Debian Ports carried much of the argument — without HFS, GRUB cannot boot PowerMacs. Any plan that assumed imminent removal was wrong.

The security argument is the one that actually decides this. These drivers have a long history of memory corruption on malformed volumes, serious enough that Debian carries a bug titled “HFS/HFS+ are insecure.” This system's whole purpose is mounting 30-year-old disk images of unknown provenance — hostile input parsed in ring 0. A FUSE process can be sandboxed and dies harmlessly when it faults. That is the better design no matter who maintains the kernel code, and unprivileged FUSE mounts suit a no-accounts live system better than a setuid mount helper besides.

Where the kernel driver still earns its place: trusted local volumes, and read-write HFS+, since hfsfuse is read-oriented. Make it a per-case choice rather than a blanket rule — userspace for anything the user just downloaded, kernel for volumes the system created itself.

6 — Classic Applications

This section decides the project. Everything else is assembly; this is the part with a real constraint, and the constraint is copyright rather than engineering.

Verified: Executor is redistributable

Cliff Matthews open-sourced Executor in 2008 under an MIT-style license (see COPYING in the source tree). It needs no Apple ROM and no Apple system software — it reimplements the classic Mac Toolbox the way Wine reimplements Win32, and installs its own synthetic system files on first run. It ships in your ISO with no legal asterisk.

One caveat worth designing around: the built-in debugger is based on cxmon, which is GPLv2+, so a stock build is effectively bound by the GPL for the whole binary. cxmon is optional and removable if you want a non-copyleft build — but for a Linux distribution shipping under the GPL anyway, this is a non-issue. Build it in.

The options, compared

Approach Apple ROM Apple system software Shippable in the ISO Compatibility
Executor
MIT + optional GPL component
Not needed Not needed Yes A subset. Many System 6 and 7-era applications run; many do not. Reimplementation coverage, not emulation completeness.
Advanced Mac Substitute
actively developed
Not needed Not needed Yes Narrower today, but deliberately Apple-code-free and moving. The honest long-term bet; pair it with Executor rather than choosing.
Basilisk II Required Required No Excellent — it is real 68k emulation. Blocked on assets you cannot distribute.
Mini vMac Required Required No Superb for Plus-era software. Same blocker.
qemu-system-m68k -M q800 Required Required No Improving quickly. Same blocker.

What “only legal methods” actually rules out

The ROM is the hard blocker, not the operating system. Apple's ROMs are copyrighted firmware and there is no licensed way to put one in a downloadable image. System 7.5.3 was famously a free download from Apple for years, but free to download is not licensed for you to redistribute, and those two get conflated constantly in retrocomputing circles.

That leaves a clean division. Ship Executor and AMS in the image, working out of the box, no setup. Then offer an optional first-run assistant that lets a user point at a ROM they dumped from hardware they own — which unlocks Basilisk II and full fidelity, entirely legally, without you ever distributing Apple's code. Shipping the dumping instructions is fine. Shipping the dump is not.

Default experience

Executor + AMS, preinstalled. Double-click a .sit, get a working application. Nothing to configure, nothing to acquire, nothing to explain. Compatibility is partial and that is an honest trade to state plainly in the documentation rather than paper over.

Enthusiast path

A ROM assistant in the System Folder. The user supplies their own dump; the system configures Basilisk II around it and the compatibility ceiling disappears. Opt-in, clearly labelled, and legally clean because the user supplies the only encumbered asset.

7 — Seamless Windowing

Nothing off the shelf gives you rootless 68k windows. But you get most of the effect cheaply, because mlvwm is already drawing System 7 chrome around everything.

Ship this — instance per application Research this — true rootless Executor instance Aboots straight into MacPaint Executor instance Bboots straight into HyperCard Executor instance Cboots straight into ResEdit mlvwm frames each borderless window Each application is one host window. Costs RAM, which is free now. Because mlvwm already draws System 7 chrome, the seams read as consistent rather than as emulation. Guest agent walks the window list, reports rects + z-order Framebuffer single shared surface from the emulator Host compositor crops regions, reprojects each into its own X window Input router maps host clicks back to guest coordinates Feasible precisely because Executor and AMS are open source — you can add the agent inside the Toolbox implementation rather than reverse-engineering a black box. This is a paper, not a milestone.
Fig. 5 — Two paths to “seamless”

The instance-per-application approach is not a consolation prize. A user launching MacPaint from /Applications gets a window with System 7 chrome that they can move, resize, and stack against a GIMP window that has identical chrome. The illusion holds for everything except overlapping modal dialogs inside a single classic application, which stay trapped in their instance's window.

8 — Sequencing

Five milestones. The first four produce something people would actually install and use. The fifth is open-ended and should be treated that way from the start.

#MilestoneDone when
1Bootable desktopISO boots to mlvwm with a ROX-Filer pinboard, no console visible, no login prompt, on both UEFI and BIOS.
2Finder + /ApplicationsDropping an AppImage into /Applications makes it appear in the menu and on the desktop within a second, and it survives reboot via the overlay.
3Archives + volumesDouble-clicking a .sit in the Finder produces a mounted HFS volume with forks intact. No terminal involved.
4Classic layerExecutor and AMS packaged; a classic application in /Applications launches from a double-click in a framed window. ROM assistant available but never required.
5Seamless windowingIndividual classic windows are individual X windows. Ship 1–4 first and treat this as a separate project with its own timeline.

Start here

The highest-information first step is milestone 1 plus a compile of mlvwm against XLibre. If the imake build fights you, you learn that in an afternoon rather than after committing to the whole architecture — and the fallback is to build against plain Xorg, which changes nothing else in this document.

9 — Risks and Trade Dress

RiskSeverityMitigation
Shipping Apple fonts or iconsHighChicago, Charcoal, and the System 7 icon set are Apple's property. Use clean-room bitmap lookalikes with explicit licenses, and check each one's terms individually — several popular “free” Chicago clones are personal-use only.
Apple logo in the menu barHighTrademark, not copyright, and no fair-use argument helps you here. Use an original mark. The placeholder in the mockup above is deliberately not an apple.
Imitating the System 7 lookLowTrade dress is a grey area, but themes of this kind have existed unchallenged for three decades and mlvwm itself has shipped since the 1990s. The risk is in the assets, not the geometry.
XLibre packagingNot a riskFew distributions package it, but building and maintaining an X server is routine work here, so this is a task rather than an exposure. mlvwm links against Xlib and is indifferent to which server is on the other side; plain Xorg stays a drop-in fallback that changes nothing else in this document.
Malformed HFS volume corrupts kernel memoryMediumThe historical risk in these drivers, and this system exists to mount disk images of unknown provenance. Handled by defaulting to sandboxed FUSE mounts; the in-kernel path is reserved for volumes the system created itself. Removal is no longer a concern — both drivers are actively maintained again.
Executor compatibility ceilingMediumReal and permanent. State it plainly in the documentation, maintain a tested-application list, and offer the user-supplied-ROM path for anyone who needs full fidelity.
AppImages assume a desktop stackMediumSome expect XDG portals, a notification daemon, logind, or a working dbus session. On Devuan that means elogind plus a minimal session bus and the portal shims — install them deliberately as a compatibility layer rather than discovering the need one application at a time.

Prior art worth reading before writing code

helloSystem has built a large share of this vision on FreeBSD, including the Finder replacement and the application-bundle model. GoboLinux is the cautionary tale for the literal System Folder. ROX-Filer supplies the desktop layer you are missing. Read all three before milestone 1; each one either saves you weeks or tells you which weeks not to spend.