Nice Things that Apple doesn’t let us have (on an iPad)

This is a follow-up to a couple of previous ramblings ( and ) about the iPad and its limitations, and is a list of things that I would love to have on an iPad, but that Apple still doesn’t really want us to in 2024, fourteen years since .

Call it product vision, use cases, or just plain old monopolistic behaviour, but I’m going to list them here in the hope that someone at Apple reads this and realises that they could make a lot of people happy by just flipping a few switches.

Oh, and having more enlightened App Review guidelines. But I digress.

A Native Terminal

This is the number one, all-day, every day annoyance that I have. We’ve had clients since the very beginning of iOS, but we never got a first-party one, let alone one with enough command-line capabilities to do simple scripting.

And yes, I know that is a can of worms, and that nobody would be completely happy with whatever Apple decided to include inside such a thing. But it’s completely feasible now.

Like I mentioned , goes a long way towards fixing that, and proves that you can do an incredible amount of stuff with a simple sandboxed environment (that is even extensible via binaries).

JITed Emulation

Yes, game emulators are a thing. Fine. I honestly don’t care–what I do care about is having something like iSH (which, sadly, seems to have gone into maintenance mode) to have a better terminal sandbox that could at least run emulated binaries at a usable pace.

And I’m using iSH as an example because I’ve been using it for far longer than , which, as I wrote , is borderline unusable but tantalisingly close to what I would love to have as a mobile development environment.

Other people (besides emulators) have more mainstream uses for JITs (like browser engines), and I really think this could be solved with a new application entitlement (and more knowledgeable people in App Review, but I want to avoid going down that rabbit hole–I’ll just say that I recently helped a pretty big company navigate that, and my blood pressure didn’t improve).

But even if could employ an actual JIT, there are literally much better ways to give developers usable tools.

Hypervisor Support

This is the Brontosaurus in the room, and the thing that frustrates me the most about the iPad from a purely technical perspective.

It’s a fact that Apple decided to remove Hypervisor.framework from XNU in iOS 16.4. This was done in October 2023, just as M-series chips finished taking over the top tiers of the iPad portfolio.

I’m not a conspiracy theorist, but removing support for something that most of your “Pro” tablet hardware portfolio could leverage to run third-party software with tremendous benefits (and perhaps taking Apple out of the equation) seems… biased?

Maybe this is the sort of thing the European Union should be looking into next. Just saying. Because, you see, removing the ability to run third-party software via virtualization when your hardware supports it should also be seen as an anti-competitive move.

Now, this is not an immediately appealing prospect for just about anybody (usability-wise), but just imagine if I could take my Windows on ARM image, copy it over to an iPad and use it to work all day without downloading any more apps from the App Store.

I know it’s technically feasible. People have made it work on jailbroken iPads–and not just “work”, but work properly.

And, after years of running Windows on ARM on several machines (including the MacBook I’m revising this on) I have a pretty good idea of how well it would work for me.

Sure, Parallels did a lot of polishing on the Mac, but works nearly as well and very few, if any of Parallels’ desktop integration features would be needed or make sense on an iPad.

And I don’t even want a desktop environment, as long as I get a console and some sort of filesystem integration–the base wrappers that we’ve had to run and Linux VMs on the Mac would be more than enough.

But that reminds me…

A Proper Filesystem

Files is a half-hearted, half-baked attempt at giving people just enough Finder features that they forget about the complete mess that lies underneath, and as someone who constantly deals with iOS file providers as I use to access Working Copy repositories or Blink’s excellent to power-edit some long-form, I would love to see it metaphorically taken out behind Apple Park and shot (politely), or at least given a very stern talking to.

Oh, wait, Apple Park is a circle. Nevermind.

Pairing an Apple Watch (starring Apple Health)

I would love to ditch my iPhone, get a cellular Apple Watch instead and just pair it to my iPad mini–which, by the way, cannot do voice calls, but I’m going to let that one slide because this list is already getting too long and I understand about handset certification.

We finally got a Health app on the iPad that is actually good enough to use (in general), so the only real reason for tethering the watch to an iPhone is… making sure people buy one even if their lifestyle, professional constraints (or even handicaps) make it pointless to have it.

Handling Multiple Audio Devices

This is a hobbyist musician’s gripe (and, of course, also a hipster podcaster’s concern, so I suspect it might get more visibility that way), but the iPad is completely hopeless at handling external audio devices.

MIDI, being a simple signalling protocol, works fine, but multi-channel audio, despite (finally) getting a modicum of support in Logic Pro for iPad, is still a mess and isn’t properly supported anywhere in the iPad’s standard UI.

So routing inbound and outbound audio along different device paths falls somewhere between a crapshoot and no option at all.

Use The Trackpad in Continuity

And finally, being unable to control a Mac’s mouse with a local trackpad or mouse when you use Continuity to extend (or mirror) your Mac’s display to an iPad makes me absolutely certain that Apple does not want people to run macOS on an iPad, either vicariously or by proxy.

$DIVINITY forbid that I should be able to use my iPad to use my desktop Mac from my couch. That would be too much, and certainly a missed opportunity for me to by a MacBook Air.

Oh, and I just realized that I was only able to use a mouse with my iPad in 2016 because . We only got official mouse and trackpad support anyway…

Bonus Round: Multi-User Support

This was the first feedback I got within minutes of this going online, and I have to agree. I’ve been so used to the way Apple thinks of iPads as single-user devices that it was a blind spot in my criticism.

Multi-user support is already supported in educational settings, and I distinctly remember that the Nexus 7 (we actually owned two that I bought off eBay for my kids) supported that out of the box six years ago. Android tablets seem to have quietly dropped or hidden the feature as well (haven’t tried any recent ones), but even a 128GB iPad has enough storage for two people to use it comfortably for e-mail, browsing and media consumption.

Conclusion

Instead of any of these, we got ChatGPT and… a calculator.

Thank you, Apple.

In the meantime, I will keep using and will be looking closely at things like the Minisforum V3 (which by all accounts can run Linux perfectly, “ticks all the boxes” in Bad Gear parlance and is already on my wishlist).

Notes for July 15-21

This was a very productive week in personal terms (and otherwise), partly because I paused my reading spree and partly because I decided to clear out my To-Do list as quickly as possible.

Productivity Tweaks

  • Resumed my regular cleaning of my desk at the start of the week, which resulted in a (short) bit of Zen-like calm.
  • Removed the battery from my pre-release and moved it permanently to my standing desk.

It works fine via USB, and makes quite a bit of difference ergonomically (I now have two of those in daily use, which is definitely a first world problem).

Home Automation

With 37oC being forecast for next Monday, I decided to grab a handful of Demos D1s I still had in stock, flash them with my custom firmware and pop open all the heat pumps to add them to HomeKit.

Wrapping the boards in Kapton tape

Having working thermostats in nearly every room makes a bit of a difference.

3D Printing

  • Splurged on Amazon Prime Day on stuff I probably don’t really need (except for the ASA filament).
  • Spent a few evenings trying to get my TwoTrees SK1 to work properly again after what I believed to be a calibration attempt gone wrong. I later realised that the Y axis shift I was seeing was due to the cable chain preventing the print head to home properly with on.

I still have to finish calibrating it, but at least now I know why it was failing.

Homelab Maintenance

I decided to do a bit of actual hardware maintenance:

Fitting a new, quieter heat exhaust fan to rogueone
  • Shut down both my Synology NAS and , opened them and dusted them off with a neat (and surprisingly powerful) air blower I had gotten a while back. Much more effective and satisfactory than compressed air canisters.
  • Took that opportunity to finally add a Crucial 2TB SSD to the to act as read-only cache–I should have done this years ago, since it made a few services I run on it (like ) an order of magnitude faster…

Software Archaeology

  • Found an ancient 38 LXC inside my while revisiting an old project and brought that kicking and screaming into the 40 age. Still sad that I can effectively run what amounts to a VM inside the machine I use as a development sidecar for my iPad, but hey too.
  • Installed BasiliskII on the and built a complete System 7.5.5 image to recover a few old files (essentially the Mac version of the archive spelunking I did ).
This is Office 4.2. All if it, in less than 60MB on disk.

I already have a Raspberry Pi running MacintoshPi, but this one I can access via remote desktop…

AI Stuff

I also spent a little time playing with gpt-4o-mini (it’s already available in preview in Azure Open AI) and planning the next steps for moving all of my gpt-3.5-turbo services over to it (which will involve a few prompt tweaks). The price per token vs the overall quality makes it really hard to justify using local LLMs, but I hope we’ll see enough improvements in inference speed to flip things around within a year.

I’ll get back to that next week–but first, I have a fair amount of soldering to do, since a chunk of the parts I was waiting for finally arrived.

The Luckfox Pico Mini B

A while back during my spate of RK3588 reviews, I came across Luckfox and found their development boards intriguing, since they were marketed as being able to run Linux in the same postage stamp form factor as an MCU.

That seemed pretty amaazing, so I reached out to them and got a sample.

Disclaimer: Luckfox provided me with a Luckfox Pico Mini board and a CSI camera (for which I thank them), and this article follows my .

What followed has been a surprisingly pleasant experience, and I’ve been tinkering with the Luckfox Pico Mini on and off for a few weeks now–to be fair, mostly off given several work shenanigans, but that’s beside the point right now…

Hardware

I got the B model, which has a soldered on 128MB SPI NAND flash:

Both sides of the board, which is pretty compact.

The specs for the version I got are:

  • Single Cortex A7 1.2GHz core
  • 0.5 TOPS NPU (with int4, int8, int16 support, so it can run OpenCV and simple neural networks, but nothing too fancy)
  • 64MB RAM
  • USB-C 2.0 host/device connector
  • CSI connector (I also got a 3mp camera)
  • MicroSD connector
  • 17 GPIO pins

An intriguing part of the RV1103 chip that I haven’t explored is that it includes a RISC-V MCU and an integrated signal processor for speeding up camera operations–I intend to play with that at some point, but simply haven’t had the time yet.

If you’ve been following along in the and space, you’re certainly wondering about price right now, since the overall specs compare pretty favourably with similarly sized and boards, especially if you consider its secret sauce–i.e., running Linux natively.

Right now it’s selling for $8.99, which is around twice the price of similarly-sized boards, but which still looks like a bargain if you need the extra processing power and the ability to run Linux.

On the flip side, this particular model doesn’t have wireless connectivity, which is a bit of a bummer. But I can see how that would complicate the design and increase the price further.

I’d say we’re about a year away from seeing a Cortex A7 with wireless connectivity at this price point, but don’t hold me to that.

Going In Headfirst

Since the B version of the board has on-board storage and comes pre-flashed with a working 5.10 kernel, I decided to see how far I could go with the board as it comes out of the box.

Connecting

I plugged the Luckfox Pico into one of my Linux machines, and it showed up immediately as a RNDIS device:

 dmesg

[57790.089476] usb 3-2: new high-speed USB device number 3 using xhci_hcd
[57790.220263] usb 3-2: New USB device found, idVendor=2207, idProduct=0019, bcdDevice= 3.10
[57790.220280] usb 3-2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[57790.220287] usb 3-2: Product: rk3xxx
[57790.220292] usb 3-2: Manufacturer: rockchip
[57790.220298] usb 3-2: SerialNumber: c800c8d03cffebb8
[57790.333460] usbcore: registered new interface driver cdc_ether
[57790.341712] rndis_host 3-2:1.0 usb0: register 'rndis_host' at usb-0000:04:00.4-2, RNDIS device, ae:5c:b5:d3:ee:1e
[57790.341790] usbcore: registered new interface driver rndis_host
[57790.380103] rndis_host 3-2:1.0 enp4s0f4u2: renamed from usb0

This means there’s none of the usual serial port/FTDI-style shenanigans (well, when you’re not flashing it, of course). Instead, you have to do some TCP/IP shenanigans.

My host machine auto-generated the enp4s0f4u2 interface, but if you need to flash a number of these and keep inventory, here’s a quick snippet to figure out the right interface from the MAC address without going into dmesg:

 ip addr list | grep -B 1 -A 2 ae:5c:b5:d3:ee:1e

5: enp4s0f4u2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 1000
    link/ether ae:5c:b5:d3:ee:1e brd ff:ff:ff:ff:ff:ff
    inet6 fe80::f8c1:e2a2:dd8a:c6c1/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever

As you can see, there’s no assigned IPv4 (only the system-assigned link-local IPv6 on the host side). And the Luckfox Pico does not support RFC 3927, so you don’t get an automatic link-local IPv4 address.

The docs specify the default IP as 172.32.0.93, so let’s set an address at our end and test the Ethernet over USB link:

 sudo ip addr add 172.32.0.1/16 dev enp4s0f4u2
❯ ping 172.32.0.93                             
PING 172.32.0.93 (172.32.0.93) 56(84) bytes of data.
64 bytes from 172.32.0.93: icmp_seq=1 ttl=64 time=0.754 ms
64 bytes from 172.32.0.93: icmp_seq=2 ttl=64 time=0.580 ms
^C
--- 172.32.0.93 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1008ms
rtt min/avg/max/mdev = 0.580/0.667/0.754/0.087 ms

It feels a bit weird to log in to what is almost an MCU via ssh, but it works fine:

 ssh [email protected]
The authenticity of host '172.32.0.93 (172.32.0.93)' can't be established.
ED25519 key fingerprint is SHA256:VnUEEITBSJ7Y7h+wmk8bTqw47QwdLWudvM0tRgke4Kc.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '172.32.0.93' (ED25519) to the list of known hosts.
[email protected]'s password: 
# uname -a
Linux luckfox 5.10.110 #1 Tue Nov 14 18:06:04 CST
 2023 armv7l GNU/Linux
# cat /etc/issue 
Welcome to luckfox pico

Running Processes

The runtime is, as you’d expect, pretty sparse, and on the base image there aren’t a lot of things besides kernel workers:

# ps -ef
PID   USER     COMMAND
    1 root     init
    2 root     [kthreadd]
    4 root     [kworker/0:0H]
    6 root     [mm_percpu_wq]
    7 root     [ksoftirqd/0]
    8 root     [kdevtmpfs]
    9 root     [oom_reaper]
   10 root     [writeback]
   11 root     [kcompactd0]
   12 root     [ksmd]
   28 root     [kblockd]
   29 root     [kconsole]
   30 root     [devfreq_wq]
   31 root     [watchdogd]
   32 root     [kworker/0:1-eve]
   33 root     [rpciod]
   34 root     [kworker/u3:0]
   35 root     [xprtiod]
   36 root     [kswapd0]
   37 root     [nfsiod]
   38 root     [irq/60-rockchip]
   39 root     [irq/61-rockchip]
   40 root     [kworker/u2:1-ev]
   41 root     [hwrng]
   42 root     [spi0]
   51 root     [kworker/0:3-eve]
   52 root     [irq/22-rockchip]
   53 root     [kworker/u2:2-ev]
   54 root     [ubi_bgt0d]
   57 root     [ubifs_bgt0_0]
   73 root     /sbin/syslogd -n
   77 root     /sbin/klogd -n
   88 root     /sbin/udevd -d
  141 root     [ubi_bgt4d]
  146 root     [ubifs_bgt4_0]
  155 root     [ubi_bgt5d]
  160 root     [ubifs_bgt5_0]
  182 root     [irq/50-ffa70000]
  200 root     [irq/41-rga2]
  202 root     [queue_work0]
  203 root     [queue_work1]
  204 root     [irq/48-ffa50000]
  205 root     [irq/49-ffa60000]
  206 root     [vcodec_thread_0]
  208 root     [rknpu_power_off]
  215 root     sshd: /usr/sbin/sshd [listener] 0 of 10-100 startups
  246 root     [vlog]
  247 root     [vsys]
  248 root     [vrga]
  250 root     [vpss]
  251 root     [vrgn]
  253 root     [vmcu]
  326 root     /usr/bin/adbd
  334 root     [irq/62-dwc3]
  370 root     smbd -D
  373 root     {smbd-notifyd} smbd -D
  374 root     {smbd-cleanupd} smbd -D
  379 root     nmbd -D
  384 root     /sbin/getty -L console 0 vt100
  397 root     sshd: root@pts/0
  399 root     -sh
  409 root     ps -ef

Wait, is that… Samba? Seriously?

# cat /etc/samba/smb.conf 
[global]
        workgroup = WORKGROUP
        server string = luckfox samba server
        security = user  
        passdb backend = smbpasswd
        smb passwd file = /etc/samba/smbpasswd
[public]
        comment = public share
        path = /
        read only = no
        user = root
        create mask = 0755
        directory mask = 0755# 

Yep. This when you start realizing the Luckfox Pico is an embedded system you can mount over –crazy times.

Running My First Binary

At the time I got this I didn’t have any cross-compilation environments set up, but I did have , and I have a fairly long history of building impromptu binaries for weird ARM architectures using, it.

So I thought I’d add to that list:

 go mod init luckfox/hello

...a few moments later...
❯ cat hello.go 
package main

import "fmt"

func main() {
        fmt.Println("Hello, Luckfox!")
} env GOOS=linux GOARCH=arm GOARM=7 go build -o hello.armv7

❯ file hello.armv7 
hello.armv7: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, Go BuildID=fMvkSlf1kYWYnV88GhTQ/J1Y1phDV859SF5L4bFxZ/P3d-713IBZ6mHIbEpIub/hZRSRS5aBTm4NBaU8f_g, with debug_info, not stripped

❯ scp hello.armv7 [email protected]:~/

...a few moments later...

# ./hello.armv7
Hello Luckfox!

The resulting binary is 1823294 bytes in size (which is reasonable given that it is fully static), and the other (relatively simplistic) stuff I’ve built since hasn’t yet crossed the 2MB mark. And keep in mind this isn’t TinyGo, it’s the full-fat Go runtime.

A few days later, while rummaging around, I realised that the Luckfox Pico ships with 3.11. Not MicroPython, mind you, but, again, the whole thing (or at least a good chunk of it that it hasn’t mattered yet).

I’ve since built some binaries, and eventually realized I can actually run gdb locally on the device–which is the kind of frictionless, iterative development approach that I love.

This opens up the opportunity for taking existing or code that would be a pain to port to Arduino or a simpler MCU and just cross-compile and copy across and test it within an hour or so, which is pretty great.

GPIO Control

The Luckfox Pico Mini has the usual set of GPIO pins, overlapping with 4 UARTs, an SPI interface and an I2C one:

Pinout for the Mini A/B models

The nice thing about having a Linux kernel is that GPIOs are mapped as device folders under /sys/class/gpio, so literally anything can use them without special libraries.

However, there are shipping libraries to make things easier, and the documentation covers that in detail–there’s a C example in the Luckfox Wiki that demonstrates GPIO access, and matching ones for I2C, SPI, etc.

Sadly, there’s no I2S support on this model–so my initial idea of getting a PCM5102A DAC to work didn’t pan out.

Building and Flashing New Firmware

I didn’t yet have time to build anything truly complex (I was planning to incorporate the Luckfox Pico into a little audio project, and now I am considering other uses), but since that’s usually something I very much want to do, I investigated how to go about it.

In short, there’s a set of comprehensive docs regarding getting an SDK going on Ubuntu 22.04, and a public repository (not on Github, though) with reference tarballs and patches for various libraries. Given the propensity of Rockchip SDKs to come with assorted binaries, I’d be prepared for a little work, but couldn’t see anything too out of the ordinary.

As to pre-built images, as usual with Chinese companies they’re available via Google Drive download (I’m not a fan of this, but it’s a common practice), and the flashing process is pretty straightforward.

A Nice Surprise

On that note, to my surprise, Luckfox actually has Linux and MacOS instructions for flashing, so the that I got expressey to deal with Rockchip tools for the RK3588 boards sat this one out.

Connectivity

My original idea was to leverage the Cortex A7 for building a tiny synthesiser with a bit more oomph than the ones that have been making the rounds–but that hasn’t come to pass, and the lack of wireless connectivity prevents me from using it in my home automation projects.

But with four UARTs, you can hook up more MCUs and use the Luckfox Pico’s SD card as a sensor data logger as well–I can see this being used in drones and other applications where you need a bit more processing power than a typical MCU.

What I eventually did was to force route the Luckfox Pico through my Linux machine and play around with little TCP servers on it. This is a bit of a kludge, but it works even if it’s not an elegant solution.

Conclusion

So who is this for? Well, for starters, I’d say the Luckfox Pico is for people who already have a code base that absolutely requires full POSIX compliance or is already running on ARMv7 chips and don’t want to mess with the complexity of porting it to a “plain” MCU.

And, in a nutshell, that’s why I have been tinkering with it–I can get something working, build an ARM binary, and copy it across in seconds–or just let the Luckfox Pico route through my machine and fetch the binary from there, without using any board-specific tools whatsoever. That’s something you can’t do with any other development board this size.

I haven’t yet had the time to play with RKNN inference and the baked in YOLO support–I need a quieter time, and will update this post when I get aroudn to it–but I can see the Luckfox Pico being used as a smart, field-programmable part inspector in manufacturing, or a tiny, self-contained auto-tracking camera (like the I’ve been using).

But given that this is an A7 with a pretty decent FPU, I’d say signal processing appliations would be a great candidate (I’m still stuck on the idea of using it as the core of a tiny synthesizer, even without I2S).

Running NixOS on ARM LXD/LXC

I decided to build a little sandbox to take with me when traveling, and investigated how to do that on my without breaking the entire thing.

Read More...

Notes for July 8-14

Work keeps taking , and I have an uneasy feeling (OK, a dead certainty) that isn’t finished yet–and yes, I’m considering various alternatives, but the current context is very far from ideal.

Read More...

A bit more regarding UTM SE on the iPad

I spent a few hours trying out (which, if you’re new here, is a version of the front-end for that runs on ) on my , and quickly came to the conclusion that it is not really usable to do local development out of the box.

Read More...

Enclosing the TwoTrees SK1

This weekend I took the time to assemble the enclosure for my CoreXY 3D printer. I had been looking forward to this for a while, but I had to wait until I had a few hours to spare and a clear workspace to do it.

Read More...

Notes for July 1-7

It’s a new fiscal year at work, and the mood is still extremely sour due to both and the usual amount of reorgs. I spent a lot of time and energy actively avoiding thinking about all of it outside working hours–along with US politics, warfare, and other heavy topics.

Read More...

The GMKtec NucBox G2

It’s time for another hardware post, this time about an Intel N100 machine–and yes, I definitely have too many machines at this point, but there’s a method to my madness.

Read More...

A Short Rant on the Current State of Computing

The other day I was trying to use my iPad to do some work and realized that WWDC had come and gone without any mention of a single feature that would actually make it easier for me to do what most people would consider real work on it, and started typing a few notes.

Read More...

Notes for June 24-30

I spent most of my free time this week mostly talking to people, since I would like to have a bunch of things sorted out before Summer sets in (the season itself appears somewhat indecisive since it’s been raining for a couple of days now, but I know what I want).

Read More...

Self-Hosting Kusto

This is going to be an unusual one, partly because it is about a product (which ) and partly because it’s going to be a bit of a brain dump.

Read More...

Archives3D Site Map