Getting closer to Classic on Linux on ppc64le
There are still some pain points left (other than the lack of working KVM-PR in Mac OS 9); sound is still somewhat of a work in progress if it works at all and there is no copy-paste. Many games won't work properly either. However, QEMU Mac OS 9 guests can (with assistance) now support tablets with now much more natural mouse movement, using ndrv you can run at multiple convenient resolutions, files can be exchanged over AFP via Netatalk, and if you're willing to put up with a little clock madness QEMU can "sleep" so that you're not sucking CPU cycles in the background.
You'll need an ISO and/or CDROM of Mac OS 9 to get started. I won't provide you this and merely assume you have a perfectly legal source for one, such as ripping the installation CD you already own. (I own several.) Some of these steps I've already gone through in our earlier QEMU articles but they are reproduced here for convenience. These instructions are not OpenPOWER-specific in general and should work for other Linux systems (I'm on Fedora).
- Create your disk image, usually qemu-img create -f qcow2 classic.img 40G or some such. We will refer to this image as classic.img in the example commands below.
- If not already configured set up tap networking, typically with something like this for tap0, with your username being billg:
sudo ip tuntap add dev tap0 mode tap user billg
sudo ip link set tap0 up promisc on
sudo brctl addif virbr0 tap0 (optional, but handy for libvert)This will persist until reboot.
- Download the custom video driver qemu_vga.ndrv from Github. I put it in ndrv/qemu_vga.ndrv.
- Set up your initial boot string. Mine looks like this, assuming you're booting from your Mac OS 9 ISO (in iso/922.iso):
qemu-system-ppc -M mac99,accel=tcg,via=pmu -m 1536 -drive id=root,file=classic.img,format=qcow2,l2-cache-size=4M -usb -netdev tap,id=mynet0,ifname=tap0,script=no,downscript=no -device rtl8139,netdev=mynet0 -rtc base=localtime -L ndrv -prom-env resolutions=640x480,800x600,1024x768,1152x864,1280x800,1440x900,1920x1080 -boot d -cdrom "iso/922.iso"
This gives you the maximum 1.5GB of RAM Mac OS 9 supports. You'll notice we haven't enabled the tablet yet; we'll get to that.
- Start up Mac OS 9 and install to your hard disk. When this is done, shut down the emulated Mac (QEMU will close).
- Download our "essentials" ISO from the Floodgap gopher server (Firefox will need either OverbiteWX or OverbiteNX). It contains this USB tablet driver, the freeware 1.4 version of USB Overdrive, the Network Time control panel (for talking to RFC 868 and NTP servers) and an RTL8139 Ethernet extension. Uncompress it and bring up your system booting from the hard disk image but with the ISO ready. We'll assume it's in iso/essential.iso:
qemu-system-ppc -M mac99,accel=tcg,via=pmu -m 1536 -boot c -drive id=root,file=classic.img,format=qcow2,l2-cache-size=4M -usb -netdev tap,id=mynet0,ifname=tap0,script=no,downscript=no -device rtl8139,netdev=mynet0 -rtc base=localtime -L ndrv -prom-env resolutions=640x480,800x600,1024x768,1152x864,1280x800,1440x900,1920x1080 -cdrom "iso/essential.iso"
- Mac OS 9 should have StuffIt Expander built-in. Uncompress USB Tablet and put it in the System Folder's Startup Items (it's an app, not an INIT or CDEV). Uncompress the RTL8139 extension and put it in System Folder, Extensions. The others are optional but recommended; uncompress and install as they direct. Set your desired screen resolution of the ones available (I use 1440x900 on my 1080p display) and shut down again. Here's our last boot string change, adding the tablet this time:
qemu-system-ppc -M mac99,accel=tcg,via=pmu -m 1536 -boot c -drive id=root,file=classic.img,format=qcow2,l2-cache-size=4M -usb -netdev tap,id=mynet0,ifname=tap0,script=no,downscript=no -device rtl8139,netdev=mynet0 -rtc base=localtime -L ndrv -prom-env resolutions=640x480,800x600,1024x768,1152x864,1280x800,1440x900,1920x1080 -device usb-tablet
Incidentally, if you want to build the USB Tablet app yourself, I was able to do so by downloading the project, resource and source file, converting the .r and .c files to Mac line endings, and opening the project in CodeWarrior 7 on my MDD G4.
- Mac OS 9 will now boot up, and once USB Tablet is run, your mouse will suddenly switch to tablet mode. No more mouse grabbing needed. Nice!
The next thing to do is get networking operational, because this is how we'll share files. Regular EtherTalk doesn't work but AFP-over-TCP does and Netatalk supports it. (You could of course install something like DAVE and use samba, but Mac OS 9 has AFP-over-TCP support built in and Netatalk preserves resource forks.)
- Configure your network within Mac OS 9 from the TCP/IP control panel. As we have it configured here it should be sufficient to just get an address over DHCP (from QEMU).
- Set up Netatalk. Depending on how it's built you may or may not get any of the authentication options to work; mine didn't with the Fedora package even though the emulated Mac could talk to my usual Sawtooth G4 fileserver with a password. I eventually just set up guest access to a single interchange folder that runs as me, because all of my office systems including the T2 are on an independent non-routable network (if you don't have such a setup, consider binding it to an internal interface only). /usr/local/etc/afp.conf thus looks like this, assuming your username is billg:
[Global]
; Global server settings
vol preset = my default values
afp interfaces = enP4p1s0f0
uam list = uams_guest.so
guest account = billg
[my default values]
appledouble = ea
ea = samba
[Homes]
basedir regex = /home
[HFS Work Area]
path = /home/billg/HFSThis way some malicious Mac program (or more likely me fatfingering something) can't do anything more than trash the HFS folder from QEMU. enP4p1s0f0 is the NIC on the local network (from ip addr).
- Go to the Chooser. Click AppleShare (notice no servers appear, even if you set AppleTalk to Ethernet) and then the Server IP Address button, and enter your host machine's local address. If you used my example above, connect as guest and you'll get offered a drive called "HFS Work Area." Open that and you will now have file sharing operational.
- Finally, let's make it automatically mount. Since it's connected as a guest we need not preserve credentials because there are none to preserve (you could, if you wanted to, in the Mac OS 9 keychain). Make an alias of the network mount and drop it into the Servers folder in your emulated Mac's system folder. Shut down the emulated Mac and restart QEMU; the drive should automount, allowing you to instantly interchange files back and forth.
The time is a little trickier. Mac OS 9 will talk to NTP servers, but it doesn't sync on demand, thus the Network Time CDEV we offered on the Essentials ISO. Not only will this let you fix the time right away (Apple Menu, Control Panels, Network Time and click Set Time) but you can also adjust for post-2002 daylight savings in your locale by defining a new, corrected timezone.
Once we figure out the issues with split-hack and KVM-PR, we should be able to get a dramatic speed boost on OpenPOWER systems. But even as it is, the software runs well and my sizeable investment in classic Mac applications is preserved. Sure, you could do this on a PC or a modern Mac, but I'd rather do it on what every Power Mac wants to be when it grows up (and when virtualization is working should be even better).
Please don't name image files that are QCOW2 IMG, that is normally used for raw image files that can be directly accessed via "fdisk -l [IMAGE FILE]" then "mount -o loop,offset=$((512*)) /mnt"
ReplyDeleteguestfish and guestmount can be used with FUSE to open qcow2 files, but they are wildly inefficient (they spin up an emulation in QEMU and communicate with FUSE over a network socket). I prefer to use QEMU's qemu-nbd to create temporary filesystem /dev devices to attach (partprobe them if partitions don't show up initially) as it is faster and smoother in my experience.
In addition to being sparse, the QCOW2 format is capable of compression, just not in an initial or on-the-fly image (to my knowledge), but you can convert it to compress it "qemu-img convert -O qcow2 -c " the -c flag will cause it to compress the data in the new QCOW2, and the original file doesn't have to be a QCOW, so you can convert VMDKs or raw images to it as well.
As for virtualization, my current experiments on it with my Blackbird only allow KVM to be used if using the exact host chip. So as far as I can tell, virtualization will always give the guest a POWER9 in my case. Still it's an interesting avenue, and I wonder if the endianess will be a problem, since there's a kernel flag for KVM to allow for cross-endian virtualization, and I don't know if that's turned on, or how to use it.
I'm going to politely disagree with you on .img. There are lots of things that end in .img, not just that restricted usage.
DeleteAs for virtualization, you're talking about KVM-HV. Mac OS 9 will only work with KVM-PR, which can emulate any PowerPC chip, including big-endian ones. See prior articles in this series for its limitations, including that you need to run it in HPT instead of radix MMU mode.
Now KVM-PR is something I definitely need to look into. Unfortunately at current using modprobe -r kvm_hv causes kernel panics and soft lockups on cores until a reboot on my Fedora 31, so I'll have to take some time later and investigate some more. Trying to use kvm with both enabled on qemu-system-ppc tells me it isn't there, and using it with defaults on qemu-system-ppc64 is definitely using kvm_hv. I'll have to mess around with rd.blacklist and the blacklists files later to see if I can get kvm_pr working properly on my system.
DeleteNot sure why modprobe -r kvm_hv is giving trouble, but you can't run KVM-PR in radix MMU mode, and Fedora defaults to radix. You can only run it by putting the kernel in HPT mode.
DeleteSorry, I had disabled that. I've also finished my blacklisting of the kvm_hv module. The result is puzzling, but may be a regression since your last article.
Delete[min@thea ~]$ grep MMU /proc/cpuinfo
MMU : Hash
[min@thea ~]$ lsmod | grep kvm
kvm_pr 144641 0
kvm 365360 1 kvm_pr
[min@thea ~]$ ls -l /dev/kvm
crw-rw-rw-. 1 root kvm 10, 232 Mar 31 16:28 /dev/kvm
[min@thea ~]$ groups
kvm disk wheel min dialup
[min@thea ~]$ qemu-system-ppc -enable-kvm
qemu-system-ppc: -machine accel=kvm: No accelerator found
[min@thea ~]$ qemu-system-ppc64 -enable-kvm
qemu-system-ppc64: warning: Failed to set KVM's VSMT mode to 8 (errno -22)
qemu-system-ppc64: No large decrementer support, try cap-large-decr=off
[min@thea ~]$ qemu-system-ppc64 --version
QEMU emulator version 4.1.1 (qemu-4.1.1-1.fc31)
Copyright (c) 2003-2019 Fabrice Bellard and the QEMU Project developers
[min@thea ~]$
Bad news: I could confirm your issue with modprobe -r kvm_hv. I sent that to the KVM folks, it looks like a kernel bug.
DeleteGood news: You don't have to remove or blacklist it. If you take the examples from the previous articles (under the KVM category) and change qemu-system-ppc to qemu-system-ppc64, as long as you specify the CPU (e.g., -cpu nitro) it will automatically use PR when necessary. I was able to successfully boot my Tiger VM with KVM-PR that way.