Setting up a Raspberry Pi 4 as an development machine for your iPad Pro
Years ago when I was just starting out in my career, a couple of friends and I came together with a new startup idea. The plan was to take a few days off from work, get a hotel room somewhere (co-working spaces were almost non-existent then) and start hacking out our new exciting prototype. However, we were a bit stuck because of our computers.
I had just started my job a couple of years then, and only had a self-assembled full tower computer at home but nothing portable. My better-funded friend had a laptop and said he could borrow another from someone else for me, while the other friend said he has his own portable computer.
We went about doing our own planning, and when the day came, we were pretty dumbfounded by my friend’s ‘portable computer’. I didn’t manage to take a picture — no one have a casual habit of carrying cameras then and anyone wanting to take a picture with his phone would be considered a raving lunatic (how do you stick a roll of film into a phone)?
His ‘portable computer’ was his mid-tower machine in a red supermarket shopping plastic bag, stuffed along with his mouse, full sized keyboard and power cables. His plan, as he explained after we picked our jaws off the floor, was to connect it to the TV in the hotel room.

Portable computers have come a long way since then.
Tools of the trade
I develop mostly using Go but I also occasionally still do some Python (for data science stuff) and Ruby (something quick or working on my older projects). While most of my work focused on the web, I do occasionally do lower-level development. This generally means I need to access the machine itself and have the ability to install libraries and packages that I need, access to console and a good text editor or IDE.
My main development machine is a MacBook Pro, which combination of power and portability is the best fit for me. Portability is important for me because I move around quite a bit and frankly I want to develop whenever and wherever I want to. I already use the iPad Pro quite extensively for many things including reading, surfing, emailing and chatting. Question is, can I also do software development on it?
Developing on the iPadOS is tough hill to climb because it’s a walled garden. While there are some ways to run Python, Ruby and even Java on the iPadOS now but there are significant limitations. That leaves us with developing software on the iPad Pro but as a conduit to another machine elsewhere.
Technically speaking I can develop everything over the web by spinning up servers or virtual desktops on the cloud. Realistically though, it’s too slow, even if your cloud server is within the same country and your country is pretty small. Also, if you’re offline (maybe on a plane or in a remote location without Internet access) you’re pretty much stuck if your development machine is on the cloud.
When all fails, DIY
The idea for an offline Raspberry Pi development machine instead of going to the cloud is not new, neither with me nor with many who caught the Pi fever. The idea is instead of spinning up a new server on the cloud to fulfil your needs, just connect it to a Raspberry Pi. The Pi is cheap enough and runs Linux and you can stick it into your bag and bring it along with you everywhere.
There were generally two problems. One is how to power the Pi since it doesn’t have a built-in battery. Of course you can power it externally connecting to a wall socket and a power adapter but reduces its portability and you need wall sockets for it to work. Alternatively, you can also connect it to a mobile power bank. Depending on the rating on the power bank, it could run comfortably for a few hours, but of course, this also means you need to lug a power bank along with you.

The second problem is how to make the data connection to the Pi. There are two ways of doing it, the first is to use the built-in ethernet port. Simply, use an ethernet cable and connect it to your iPad Pro. However, this means you need an adapter or hub that has an ethernet port that will connect to your iPad Pro, making the whole thing a bit unwieldy (especially if you add in the power cables).
The other option is to use wifi. The Pi has built-in wifi. We make the iPad Pro a hotspot, and then connect the Pi to the hotspot. This causes some issues though — because you now make the iPad Pro a hotspot, it can no longer use its wifi, you can only use the cellular data connection. But it works. Unfortunately there are speed issues and you’re not much better off than just spinning a server on the cloud with it.

There’s another middle-ground way though, and one that appears pretty elegantly with the Raspberry Pi 4 Model B. The Pi4 has few interesting hardware changes (which I won’t elaborate, you can find out easily from the Internet elsewhere) but what is pretty helpful for our cause is the fact that the Pi4 has a USB-C port, which you can power it with, but also use it to transfer data.

You can see where this is going. By sticking a USB-C cable from iPad Pro to the Pi4 we solve both the power and data connectivity issues with a single cable!
How to make your Pi4 a gadget
To repeat — if we connect the iPad Pro (the one with the USB-C port) to the USB-C port of the Pi4, we can power the Pi4 directly from the iPad Pro. At the same time, the cable also act as the data conduit — we just need to convince the Pi4 to consider the USB-C port as an ethernet port.

The way we do it is to set up the Pi4 as a USB ethernet gadget.
USB gadgets
Before we start, let’s understand a bit what a USB gadget is.
A USB Linux gadget is a device that has a UDC (USB Device Controller) and can be connected to a USB host (like a computer or an iPad Pro) to extend it with additional functionalities. A gadget is defined by a set of configurations, each of which contains one or more functions. In our case, what we’re doing is setting up the Pi4 as a USB Linux gadget with the ethernet over USB function.
Note that this method works well for the Pi4 Model B and Pi Zero (and also Raspberry Pi 3 A+) but not for other Raspberry Pi models because the hardware itself doesn’t support data transfer the same way.
Make your Pi4 into an ethernet gadget
Let’s get started.
I use Raspbian (Buster is the current version as I was setting this up) because I’m more familiar with Debian — you can try other distros you prefer.
First, we need to set up the Pi4 as the gadget using the dwc2 driver in device tree overlay, then load it up.
- Add
dtoverlay=dwc2to the/boot/config.txt - Add
modules-load=dwc2to the end of/boot/cmdline.txt
Next, we need to enable the libcomposite driver. You might see some tutorials using the g_* series of drivers (eg g_ether) but for these you can only load one at a time whereas libcomposite allows you to load up whichever is needed through configuration, so libcomposite is the better choice (in my opinion).
3. Add libcomposite to /etc/modules
The next step is where we configure our gadget. To do this we set up a script to run when booting up. In this script we will do the following:
i. Create a directory to represent the gadget
ii. Set up the various gadget parameters including the vendor ID, product ID etc
iii. Under the directory create the configurations and instantiate the USB function we need. In this case we will use the the ECM (Ethernet Control Model)
iv. Associate the function to the configuration with symbolic links
v. Activate the gadget by writing the UDC name (in /sys/class/udc) to the UDC attribute
4. Create /root/usb.sh to implement the steps above.
#!/bin/bash# create a directory to represent the gadget
cd /sys/kernel/config/usb_gadget/ # must be in this dir
mkdir -p pi4
cd pi4# the USB vendor and product IDs are issued by the USB-IF
# each USB gadget must be identified by a vendor and
# product ID
echo 0x1d6b > idVendor # Linux Foundation
echo 0x0104 > idProduct # Multifunction Composite Gadgetmkdir -p strings/0x409 # set it up as English
# The configuration below is arbitrary
echo "1234567890abcdef" > strings/0x409/serialnumber
echo "Chang Sau Sheong" > strings/0x409/manufacturer
echo "Pi4 USB Desktop" > strings/0x409/product# create a configuration
mkdir -p configs/c.1
# create a function
# ECM is the function name, and usb0 is arbitrary string
# that represents the instance name
mkdir -p functions/ecm.usb0 # associate function to configuration
ln -s functions/ecm.usb0 configs/c.1/ # bind the gadget to UDC
ls /sys/class/udc > UDC # start up usb0
ifup usb0
# start dnsmasq
service dnsmasq restartAfter this make sure the script is executable and set it up to run when the Pi4 is started.
5. Make /root/usb.sh executable with chmod +x /root/usb.sh
6. Add /root/usb.sh to /etc/rc.local before exit 0
Set up the networking for usb0
Your Pi4 is now configured as an ethernet gadget with the interface usb0 but we still need to make sure the rest of the networking configurations are set up properly.
Dnsmasq is an open source project that provides network infrastructure for small networks and we’ll use it for the really small network between the iPad Pro and the Pi4. It includes DNS, DHCP, router advertisement and network boot and is widely used for tethering on smartphones and portable hotspots.
7. Install dnsmasq with sudo apt-get install dnsmasq
Once you have installed dnsmasq, we need to set up it up properly for usb0.
8. Create the file /etc/dnsmasq.d/usb with following:
interface=usb0
dhcp-range=192.168.100.2,192.168.100.200,255.255.255.248,1h
dhcp-option=3
leasefile-roNow that we have dnsmasq we don’t need the standard DHCP client to muck around with usb0.
9. Add denyinterfaces usb0 to /etc/dhcpcd.conf
The final step is to set up the network interface for usb0.
10. Create /etc/network/interfaces.d/usb0 with the following:
auto usb0
allow-hotplug usb0
iface usb0 inet static
address 192.168.100.1
netmask 255.255.255.248Restart the Pi4
If you’ve done all the steps above, that’s it!
You just need to restart the Pi4, attach it to your iPad Pro and you should see a new Ethernet row under Settings coming up in a short while. This means the Pi4 is connected to the iPad Pro through an ethernet connection.

If you select the Pi4 USB Desktop setting you should see something like this. The IP address and subnet mask is assigned by dnsmasq and represents the IP address of the iPad Pro.

If you see all these your Pi4 is set up and connected!
Now that you have a development machine
So you have the Pi4 set up as a development machine and you’ve connected your iPad Pro to it. What’s next is to get the right tools on your iPad Pro to start developing. There are plenty of apps on iPadOS to choose from, but here are the ones I use.
SSH
There are plenty of SSH clients available on the iPad but the two apps I’ve tried and eventually still keep are Termius and Prompt. Both are professionally written and beautiful apps that has plenty of good features.
I preferred Termius because it allowed me to have access to the full screen and Prompt had this big top menu bar that annoyed me quite a bit. However over time what turned me off from Termius was not only its subscription model (I actually subscribed for a year) but that it increased the subscription price from about $10 a year to $10 a month. In addition, it gets disconnected from whichever server I connect to whenever I switch out and that was not usable (to be fair, its a drawback because of iOS and Termius later fixed it).
In the mean time, I discovered a different category of apps that proved to be a good replacement for SSH client apps — terminal emulators.
Terminal emulators
There are a few terminal emulators as well though not as many as SSH clients and most of them tend to be open source or free. One advantage terminal emulators have over SSH clients is that you can actually work off it directly from iPadOS! Depending on the sophistication of the emulator, it can go quite far including compiling and running applications on it.
My favourite terminal emulator by far is this pretty cool open source project called iSH, which is essentially a Linux shell environment running locally on iOS/iPadOS using a usermode x86 emulator. It’s based off Alpine Linux and you can install stuff like Python3, Ruby and even Java! However because it is an emulator there are limitations, for eg Ruby runs pretty poorly on it and there are gems that often simply doesn’t work on it. Jupyter Notebook runs on it as well (takes a long time to install) but runs really slowly (it is an emulator after all).
Also, Go and Rust doesn’t work on it either because it requires MMX instruction set emulation which it doesn’t support. It’s not a released project as of date but you can either download, compile and deploy it on your own, or sign up for a TestFlight beta trial.
Another terminal emulator I like is LibTerm, an open source project that offers a terminal experience and a number of pre-installed packages. LibTerm has Python 3.7 and Lua 5.3 pre-installed and you can even compile C! You can add other packages through the file system, which is generally whatever the Files app allows you to access.
File-sharing
Files is one of most useful apps in iPad Pro and I use it all the time to connect to my files in various cloud services as well as on the iPad Pro itself. You can also connect Files to the Pi4 through a Samba server.
Samba is an open source re-implementation of the SMB (Server Message Block) networking protocol and provides file and print services on Linux systems. For our purposes, Samba allows us to connect the Files app on the iPad Pro to directories on the Pi4. Let’s see how to do this.
First you need to install the Samba server on the Pi4.
- Install Samba through the command line.
sudo apt install samba samba-common-bin 2. Make some changes in the Samba config file /etc/samba/smb.conf
[sausheong]
path = /home/sausheong
writeable=Yes
create mask=0777
directory mask=0777
public=noThis essentially creates a shared folder in my home directory. By default Samba is set up as a standalone server, which is what we want.
3. Next, create a Samba user. The easiest is to create the same username and password, but you can use other user names and passwords else too (probably more secured as well).
sudo smbpasswd -a sausheong4. Finally, restart the Samba server.
sudo systemctl restart smbdYour Samba server is installed and set up. To make it accessible via the Files app, do the following:
- Open the Files app and select the
…and choose to connect to a server. - You will be asked to set the server, just put in the IP address (in my case, that would be 192.168.100.1) and select
Next - Enter the user name and password and select
Next.
That’s it! You should see the server appearing under the Shared heading. When you select the server you will see the files in the /home/sausheong directory in the Pi4.

Code editors
I don’t use code editors on my iPad Pro because none of the ones I’ve used fit into my normal coding workflow. Specifically when I write code or make changes to code, I expect the changes to be saved. Unfortunately most of the code editors I have tried before requires a secondary step of syncing the files to the server, which really breaks my flow.
There are a couple of exceptions, especially Kodex, which allows me to use the Files app to connect to a Samba server on the Pi4 and it works reasonably well. However I don’t like the interface (yes, I’m picky) so that was it. Having said that though, I haven’t tried the more popular code editors yet like Coda or Buffer essentially because I’m not confident that they will be worth it.
Remote desktop
With the Pi4 as a separate development machine you might also ask, why not make it a remote desktop altogether? By this, I mean using VNC (Virtual Network Computing). And of course, there’s really nothing stopping you from doing it.
For those not initiated, VNC is a graphical remote desktop system that uses the Remote Frame Buffer protocol (RFB) to remotely control another computer. It sends the keyboard and mouse events from one computer to another, and receives screen updates back over a network.
Raspbian has built-in VNC Connect from RealVNC, which includes both the VNC Server and client. We’re going to use the VNC client from the iPad Pro so we just need to enable the server on the Pi4.
Run the raspi-config tool configure the Pi4 from the command line:
sudo raspi-config
Go to Interfacing Options, scroll down and select VNC > Yes and we’re all set!
On the iPad, you need to install a VNC client. There are few but I used VNC Viewer from RealVNC to be consistent. Add a new server and enter the IP address (192.168.100.1 in my case) and name. The user name and password is the same user name and password you used to log into the Pi4 (it’s either pi or whichever user you created). That’s all there is to do, just hook up your iPad to the Pi4 and away you go!

Finally if you’re wondering even though you’re remote-ing into the Pi4, can you add a mouse to the Pi4 instead of using the rather clumsy touch interface or the rather silly remote mouse? And why not. It would be impossible if your remote desktop is really far away but this is just a small box next to your iPad, so just stick a mouse into one of the USB ports! It works pretty well.
And since you’re adding a wired mouse, why not a wireless one, heck, why not a Bluetooth mouse. That works like a charm too!
Visual Studio Code
I mentioned earlier that I don’t use code editor apps on my iPad Pro. My usual code editor is Visual Studio Code on my MacBook Pro, and unfortunately it doesn’t work on the iPadOS. However it does work on the Pi4 though it’s a bit messier to install.
VSCode is not a package not in the standard repositories. In addition, while you can download the .deb package from the VSCode site, they only have it in amd64. Remember, our nifty little Pi4 is an ARM machine so this wouldn’t work. Fortunately the Internet is full of helpful people and one such person have made all the necessary scripts to perform an easy install of VSCode.
Just follow these steps on the Pi4:
- Execute this command to set things up:
curl -s https://packagecloud.io/install/repositories/headmelted/codebuilds/script.deb.sh | sudo bash- Continue with this second command to do the actual installation:
curl -L https://code.headmelted.com/installers/apt.sh | sudo bashYou should have a working version of VSCode after this. Just go to any directory in command line and do this to open up VSCode.
code-oss .Here’s how I used VSCode on the Pi4 for my Tanuki project.









