DRAFT: This document is under revision.
Surprisingly, modern Linux still works well on 68k Macintosh. Maybe better than ever. Of course, it’s not fast, and a large Ubuntu install with GUI isn’t going to be practical.
But a middle-weight distribution like Debian 12 “minimal” install runs fairly well. Not fast, but usable.
If you really want to dig in, you’ll want to build your own kernel and root filesystem which is significantly more minimal. I believe that yields an actually quite usable install, but for now I’ll leave that as an exercise for the reader.
Table of Contents
Requirements
- A 68k-era Macintosh.
- 68020 or newer. Running anything below a 68040 is probably too painful.
- Lots of memory. Probably 64MB or more. I have 132MB.
- A large, free disk (preferably emulated), ~1GB.
- Linux computer which can run QEMU. It’s possible to get this working on macOS or Windows, but the instructions will require changes.
- If you’re using PiSCSI, you can use it to perform these steps directly.
What Works
A lot. I’ve successfully exercised the following on my machine, including some advanced stuff:
- Networking, including IPv6
- SSH access, inbound and outbound
- NuBus graphics at 24-bit (no acceleration)
So far my NuBus ethernet card has not been detected, however.
Installing Debian
As above, Debian is fairly usable and easy to get working. It’s a nice jumping-off point to get Linux working.
To simplify and speed along the installation process, we’re going to use QEMU, emulating a Quadra 800, to perform the Debian installation, then transfer that disk image to our Macintosh.
On your Linux machine, install qemu for m68k:
$ sudo apt install qemu-system-m68k
Download Debian for 68k:
- Visit https://cdimage.debian.org/cdimage/ports/
- Select the version you want (
12.0
definitely works) - Select
m68k
- Download the corresponding
iso
file. In the examples below we’ll be usingdebian-12.0.0-m68k-NETINST-1.iso
.
Extract the kernel and initramfs, using a loop mount. If you’re using other loop mounts, you may need to change
loop0
to something else.$ sudo modprobe loop $ sudo losetup -f debian-12.0.0-m68k-NETINST-1.iso $ mkdir cdrom $ sudo mount /dev/loop0 cdrom $ cp cdrom/install/cdrom/initrd.gz . $ cp cdrom/install/kernels/vmlinux-*-m68k . $ sudo umount cdrom $ sudo losetup -d /dev/loop0 $ rmdir cdrom
Make note of the filename for
vmlinux
, in this example we’ll be usingvmlinux-6.1.0-9-m68k
.Create the boot disk:
$ qemu-img create Linux.hda 1g
Now we’ll boot the installer by running QEMU headless and attach it’s serial console to our local terminal:
$ qemu-system-m68k -boot d \ -M q800 -serial none -serial mon:stdio -m 1000M \ -net nic,model=dp83932 -net user \ -append "console=ttyS0 vga=off" \ -kernel vmlinux-6.1.0-9-m68k \ -initrd initrd.gz \ -drive file=Linux.hda,format=raw \ -drive file=debian-12.0.0-m68k-NETINST-1.iso,format=raw,media=cdrom \ -nographic
Run through the installer as normal until you get to partition setup.
Here the “Guided” partition setup will not work. Select “Manual” and set things up:
- Select the drive and create the partition map.
- Select the empty partition in the new map and format it to “max” size. Use the defaults for this new partition.
- Write the partition map.
- This setup omits any swap space, you will recieve a warning while continuing. In my case I didn’t want to thrash the SD card so I continued. Configuring swap space is left as an exercise for the reader.
Continue through the installer until you reach the mirrors configuration.
Choose to manually configure the mirrors, so we can setup the m68k port mirror. Configure the following:
- Hostname: ftp.ports.debian.org
- Directory: /debian-ports/
WARNING: At this point I hit a kernel panic. If you do not, continue and complete the installer, selecting the minimal set of components for the OS.
If you do panic, hit
ctrl-a
thenx
to terminate QEMU. We’ve actually gotten far enough through the install that things will work.Once the machine has completed the install or paniced, copy the new kernel and initrd from the root filesystem:
$ sudo modprobe loop # We need to mount at this offset to skip the partition table $ sudo losetup -o 32768 -f Linux.hda $ mkdir root $ sudo mount /dev/loop0 root $ cp /boot/vmlinux*-m68k . $ cp /boot/initrd.img.* . $ sudo umount root $ sudo losetup -d /dev/loop0 $ rmdir root
Make note of the filenames, you’ll need them below. In these examples we’re using
vmlinux-6.1.0-9-m68k
andinitrd.img-6.1.0-9-m68k
.Now we need to configure the root password – it is either empty (if you hit a panic), or set to a very expensive hash method (if you finished the install). This will cause problems on this slow machine.
WARNING: We are setting very poor security here, don’t use a password you care about. And don’t put this machine directly on the internet with no firewall.
NOTE: We need to use a cheap hash method both because we don’t like waiting to login, and because the login screen times out after 60 seconds and the hash can take longer than that. We could extend the timeout instead as an option.
Boot to single user:
$ qemu-system-m68k -boot d \ -M q800 -serial none -serial mon:stdio -m 256M \ -append "init=/bin/sh root=/dev/sda2 rw console=ttyS0 vga=off" \ -kernel vmlinux-6.1.0-9-m68k \ -initrd initrd.img-6.1.0-9-m68k \ -drive file=Linux.hda,format=raw \ -nographic
At the console enter this, substituting the password you choose, to set root’s password with MD5 hashes:
$ echo 'root:PASSWORD' | chpasswd --crypt-method MD5
Update
/etc/apt/sources.list
with the following to configure the package locations. You can usepico
to edit the file:deb cdrom:[Debian GNU/Linux 12.0.0 _Sid_ - Unofficial m68k NETINST 20230516-06:51]/ sid main deb http://ftp.ports.debian.org/debian-ports/ sid main contrib non-free non-free-firmware deb-src http://deb.debian.org/debian/ sid main contrib non-free non-free-firmware
Now run:
$ apt update
You should be able to shut down again with
/sbin/shutdown -h now
. If not dosync
, thenctrl-a
thenx
again.Now Debian is setup. Copy
vmlinux-6.1.0-9-m68k
andinitrd.img-6.1.0-9-m68k
to your 68k Mac.Place the
Linux.hda
disk image somewhere your Mac can use it. A PiSCSI or ZuluSCSI will work nicely. Ordd
it into a 1GB+ physical drive.NOTE: I’ve only tried SCSI ID 0. If you use anything else, you need to switch from
sda
in step 27 to the letter corresponding to your SCSI ID (a=1, b=2, etc). It is possible this confuses the Debian init system and may require additional changes.Download Penguin onto your 68k Mac and extract the StuffIt file: https://sourceforge.net/projects/linux-mac68k/files/Penguin%20Booter/Penguin-19/
By default, Penguin is not configured to use as much memory as we need to load Linux.
- Select Penguin and do File -> Get Info.
- Set the Minimum and Preferred memory to something large, like 20000.
- Close the Info window.
Launch Penguin.
Choose File -> Settings… and configure Penguin to point at your Kernel (
vmlinux-6.1.0-9-m68k
) and RAMdisk (initrd.img-6.1.0-9-m68k
) files.Switch to the second tab and set the following command line:
root=/dev/sda2 rw console=ttyS0 console=tty0
Select File -> Boot Now. You’ll see a few prep messages go by. Assuming you have sufficient memory, the kernel and ramdisk will load and Linux will begin to boot. It can take 60+ seconds for the framebuffer to initialize, during which the system will appear frozen before kernel log messages start to appear.
Give it a good amount of time after the log messages appear. It’ll take 5+ minutes to boot to the login prompt.
Once you’re booted, log into the system as root using the password you configured earlier.
Fix the system clock. The Mac uses local time for the clock, but Linux expects UTC. You can change this behavior in Linux (with some caveats) by running the following:
$ sudo timedatectl set-local-rtc 1 --adjust-system-clock
Things should be working. You can setup your own users and install additional software through apt. Whenever you setup a user, configure their password using the same
chpasswd
method as used for root.Note that if you install a new kernel or any software that updates initrd, you should once again copy those to your Mac to update them, as in step 13.
If you’d like to boot in QEMU again, you can use the following settings. These reduce the memory to 256MB and adjust the clock skew to match a Macintosh.
$ qemu-system-m68k -boot d \ -M q800 -serial none -serial mon:stdio -m 256M -rtc base=localtime \ -net nic,model=dp83932 -net user \ -append "root=/dev/sda2 rw console=ttyS0 vga=off" \ -kernel vmlinux-6.1.0-9-m68k \ -initrd initrd.img-6.1.0-9-m68k \ -drive file=Linux.hda,format=raw \ -drive file=debian-12.0.0-m68k-NETINST-1.iso,format=raw,media=cdrom \ -nographic
Fun
If you’re curious, here’s the uname and cpuinfo on my 42MHz Quadra 650:
eharmon@sixfifty:~$ uname -a
Linux sixfifty 6.1.0-9-m68k #1 Debian 6.1.27-1 (2023-05-08) m68k GNU/Linux
eharmon@sixfifty:~$ cat /proc/cpuinfo
CPU: 68040
MMU: 68040
FPU: 68040
Clocking: 41.3MHz
BogoMips: 27.54
Calibration: 137728 loops
Useful Packages
There’s a few handy Mac-specific packages you can install on your system:
hfsutils
- Though you can natively mount HFS in Linux, this allows you to manipulate unmounted disks which can be handy.mac-fdisk
- Provides themac-fdisk
command allowing you to modify Apple Partition Maps as used on 68k machines.
To Investigate
- Disk access seems very slow. I haven’t benchmarked it yet, but both PiSCSI and ZuluSCSI-backed disks show questionable cache configuration in the syslog. This may be hampering the overall system performance. This may be a regression since 2.6: https://groups.google.com/g/linux.debian.ports.68k/c/rpi2KRWl73g. It’s also possible the correct kernel modules are no longer present by default.
Extensions
Some ideas to take this further:
You can save your Penguin config to a preferences file and set Penguin to auto-boot when the file is opened. By placing this in your startup files it should trigger Linux to boot automatically, similarly to A/UX boot process.
By installing QEMU on a PiSCSI, you could swap between booting the same image in QEMU and the Mac. However, be warned, booting QEMU and the Mac simultaneously will destroy the image.
Linux can mount HFS, so it may be possible to map
/boot
to an HFS volume, thus allowing you to automatically update the kernel and initrd used by Penguin. For instance, if you want to mount the volume namedApplications
at/apps
on every boot, add the following to your/etc/fstab
:LABEL=Applications /apps hfs auto,nofail,noatime,rw 0 2
Sources
These sources were useful in creating this guide and may be helpful to you: