Over the Christmas period, I had foolishly decided that I’d like to do some tinkering with C64 development. The plan was, as we were away, to see if I could use virtual machines, via UTM on my 11” iPad Pro.
For whatever reason – I suspect because it’s the original 11” Pro – I couldn’t get any virtual machines to work. At this point I remembered an article I’d seen about using a tethered Raspberry Pi for exactly the same thing.
Having bought a Raspberry Pi 4b some time ago, with the full intention of playing retro games on it – which lasted all of a week – it made sense to repurpose it and see if I could get it up and running as a USB gadget to use for messing around.
There are a number of tutorials online, all based on Ben Hardhill’s original, detailing how to do this with Raspian/Raspberry Pi OS. This worked great, however Virtual Code was really, really, laggy using VNC, and I also couldn’t get VICE to work.1
At work the devs are going to start using Next.js in the near term and I’ve been meaning to try playing with React since about 2015. With that in mind I thought I’d switch to building the Pi out for that purpose.
All good, but then I decided I wanted to do it with Ubuntu instead of Raspberry Pi OS, because why do the easy thing when you can over engineer something for no good reason?
A Google search led to a single forum thread detailing how to do it for Ubuntu 20.10. There isn’t an actual step by step so I wanted to detail that here.
1. Initial steps
Obviously the first thing to do is burn the Ubuntu 21.10 server image to an SD card with Raspberry Pi Imager.
Once done, don’t eject the SD card – you need to edit the following three files on your computer, before inserting into the Pi:
As a safety net, add your WiFi details to the config file by uncommenting and editing the WiFi lines. If your network name contains spaces, remember to use quotes:
wifis: wlan0: dhcp4: true dhcp6: false optional: true access-points: "Network Name": password: "Network Password"
You can optionally add an address line here as well, to specify an IP:
Once you’ve done this, add the
usb0 interface under
ethernets: eth0: dhcp4: true optional: true usb0: dhcp4: false optional: true addresses: [10.55.0.1/29]
A simple edit to add
It should look something like this when you’ve finished:
dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=LABEL=writable rootfstype=ext4 elevator=deadline rootwait modules-load=dwc2,g_ether fixrtc quiet splash
Another simple edit, adding
dtoverlay=dwc2,dr_mode=peripheral to the end of this file. On Ubuntu 21.10
dtoverlay=dwc2 already exists at the end of the file, however my limited knowledge means I don’t know if it requires one or both, so I just slapped the aforementioned after this so it reads:
# Config settings specific to arm64 arm_64bit=1 dtoverlay=dwc2 dtoverlay=dwc2,dr_mode=peripheral
The original forum thread questions if the
dr_mode=peripheral is necessary, however I
can’t be arsed to haven’t tried removing it.
You can eject the SD card now, and insert it into the Pi. The next few steps I did on the iPad, with the Pi plugged in, connected via WiFi – you’ll need to know the address of the Pi if you didn’t specify it in
If you look peek into settings on the iPad as the Pi boots up, you will see an “RNDIS/Ethernet Gadget” appear in the “Ethernet” section that appears under “Wi-Fi”. Tapping on that and you’ll eventually see a self-assigned IP and subnet mask appear – we’ll change this in subsequent steps.
2. Update and upgrade
The usual chat here, update and upgrade the install
sudo apt update && apt upgrade
Once done, reboot the Pi:
3. Install and configure dnsmasq
Install dnsmasq via apt:
sudo apt install dnsmasq
At the end of the install it will attempt to run, but will fail as
systemd-resolved is already running on port 53 – this will be resolved in the next step.
sudo nano /etc/dnsmasq.d/usb
and add the following:
interface=usb0 dhcp-range=10.55.0.2,10.55.0.6,255.255.255.248,1h dhcp-option=3 leasefile-ro port=0
According to the forum thread, the
port=0 line is the bit that disables the DNS server part of dnsmasq, to avoid the clash with
Now uncomment the last line of
# If the resolvconf package is installed, dnsmasq will tell resolvconf # to use dnsmasq under 127.0.0.1 as the system's default resolver. # Uncommenting this line inhibits this behaviour. DNSMASQ_EXCEPT="lo"
Reboot the Pi and navigate to Settings > Ethernet > RNDIS/Ethernet Gadget. You’ll now see that it has an IP address of 10.55.0.X, with a subnet mask of 255.255.255.48. You should now be able to SSH into your Pi via the 10.55.0.1 address we specified in step 1.1.
Unfortunately it appears that the Pi will only retain those settings on initial boot and any subsequent reboots where it can retain the IP lease. After that – e.g. leaving it overnight – the Pi will consistently show up on the iPad with a self assigned IP in the 169.x.x.x range. To remedy this, I’ve had to manually set the IP and subnet mask to something between 10.55.0.2-10.55.0.6 and 255.255.255.48 respectively.
During the course of burning SD cards with various images, I came across the fact that the new Macbook Pro’s SD card slots are… sub-optimal. Repeatedly there were errors in verifying images being burnt to the cards, to the point where I thought it was the Raspberry Pi Imager software. Switching to an external SD card reader every image burnt and verified successfully.
Apparently I’m not the only one experiencing issues. This is obviously not a great look for a premium machine.
Both of the Samsung SD cards I bought worked with the provided adaptors in the Macbook Pro, with no errors.
- This is after trying both the package install and building it from scratch – the package version refused to see the required ROMs, and the built version just launched a black screen. ↵
- Not entirely sure that it has to be between these two or at the end. The guide I linked to at the start suggests after