Running 9front on MacBook Pro, Early 2011 (8,1)

So last month I decided to see how an old laptop I had laying around would handle 9front. I first started with the last release, which at the time was from October 2020. To by surprise, it booted without any real issues. But upon updating to the tip of 9front, there were significant changes that broke it. Cinap was very quick to address the major issue with the RAM loading right before the latest 9front release.

Since then, I've tried to improve the user experience. Here is a rundown of the current status of my experience.

Internal Keyboard / Trackpad

The internal keyboard and trackpad does not have an i8042 controller, so spurious warnings are triggered (e.g., 'kbd: init failed') and #b/leds' don't do anything: there aren't much in the way of leds on the keyboard, except for the 'caps lock' key. I offered a patch to stop the spamming of i8042 messages for the mouse, but it hasn't been picked up yet, and for probably good reason--I most likely am doing away with too much that would affect other systems that run the stock kernel.

Trackpad is a one-button mouse

A one-button mouse is a terrible idea if you want to run Plan9. Plan9 makes extensive use of a mouse, and 9front expects at least 2 buttons (where pressing 'shift' can act as a proxy for the 3rd mouse button). I investigated a bit by running nusb/kb in debug mode, but the standard reporting by the endpoint does not include multitouch events. There are some drivers on OpenBSD and Linux for the trackpad to allow multi-finger touch, which put the endpoint in raw mode and manually translate what needs to be done. Even if a driver was ported, it's not entirely clear how that would map with mouse movements in Plan9 (other than two-finger scrolling, which I've used when drawterming). I have some ideas I want to try out, yet it's dependent on porting the trackpad driver or figuring out some way to implement multi-touch.

Del is not 0x7f

To kill a process running in a window, Del needs to be pressed. Not ^H, but 0x7f. Unfortunately, that scancode isn't sent by the internal keyboard. Fortunately, Plan 9 offers a built-in on-display keyboard, bitsy/keyboard, that can be loaded with rio(1) and can simulate the proper scancode: rio -k 'bitsy/keyboard' will do the trick. The keyboard takes the bottom third of the screen by default and I haven't figured out a way to make the keyboard a set size automatically to something smaller.

Tonight I decided to create a new keymap called 'us-mb-eject' (old-style macbooks had an 'eject' button for the optical drive). It is a slimmed down keymap file that maps F1-F5 to the mouse buttons (courtesy of the mouse-fn keymap) and also maps any modifer key (ctrl, option, cmd, shift) + the delete button to 0x7f. The actual 'fn' and 'eject' keys aren't sent at all. They're received by the device as usage events (ff0003 and c00b8, respectively), so I didn't include those in the mapping since I'm not entirely sure what I would do with them at this point that couldn't be done by mapping one of the modifer keys like command. It would also require more invasive changes to nusb/kb, which I don't want to do if I don't have to.


monitor=vga. That's it. It's Sandy Bridge, which is supported but not fully. There's no screen blanking, nor are there any modes outside of native 1280x800 at this time. Don't choose another monitor type, otherwise errors will be thrown. (I had wrongly submitted a patch that adds the management engine vid & did as a monitor: I looked at the wrong line.)

UPDATE: Screen blanking is supported. See /2021/04-20/blog post.


The initial release I used from October was able to initialize etherbcm for the ethernet port, but it never worked. I contacted Fulton, who graciously offered what he had tracked down—packets are sent, but etherbcm won't receive any packets. I debugged a bit, looking at the datasheet and the implementation to see if certain differences in procedure could have caused the problem, but no avail. On top of that, the new release of 9front completely broke etherbcm for the Macbook Pro: machine check fails. I decided to rebuild the kernel without 'etherbcm' and that allowed the machine to boot again.

But what network to use? When etherbcm turned out to be a dead end, I looked to usb tethering.

USB tethering with RNDIS / Pine Phone

I had bought a pine phone and noticed that other users had been able to tether successfully. 9front had some drivers for usb networking, but which one? I had to read up on USB CSP (Class, Subclass, Protocol) to determine how to get things to work. Initially I thought it was using the standard ether cdc protocol, since that's what the driver on the Pine Phone was using. But I finally realized that it was RNDIS. However, the 9front driver was not using the standardized CSP for RNDIS, only what certain users had found with their own cell phones. I fixed that, and submitted a patch.

There still is some setup needed on the PinePhone side to allow interaction with the larger world, and the gateway needs to be manually set, but after googling I figured out a script that I could use to make it automatic. The connection is only recognized as 10Mbps on the 9front side, altho' the Pine Phone reports it's providing a 100Mbps connection; I'm not sure why. Additionally, the ether= setting in /lib/ndb/local has to be updated if the pinephone is rebooted, but fortunately it's scriptable as well.

NOTE: if the ether= setting doesn't correspond to an ethernet
address on the machine, then the machine cannot be used as an
auth server: it will just fail silently.  Or maybe I just
am unaware of the knobs to turn. I would hope that without an
ethernet adapter someone can still start an auth server. The
networking could be setup later.

There are still times when the network drops. It begins with:

usbreadproc: bad packet: doff 36, dlen 1492, len 1536
usbreadproc: bad packet: doff 36, dlen 1492, len 1536
usbreadproc: bad packet: doff 36, dlen 1492, len 1536

then sending udp msg: i/o on hungup channel messages plague /dev/kprint, but I think I got a workaround so that I don't need to restart the machine: disconnect the usb, unbind the etherU network, and kill any ip/ipconfig left around. Then start up ipconfig again. Note that there will be 3 successive usbreadproc: transaction error messages when the usb cable is connected, but usually the Pine Phone will be recognized again.

USB tethering with RTL 8150 adapter

Another USB tethering option that works is by using an RTL 8150 adapter for a wired connection. I bought a Linksys USB100M adapter, and that works fine: it provides a —100Mbps—10Mbps connection. You don't want to jostle the connection, as the connection is delicate for the USB100M.


The built-in wireless adapter is a BCM 4331. There's a reverse-engineered implementation that presumably works well on Linux (search bc43xx), so that would have to be ported for it to work.

Web camera

The web camera is recognized on the USB hub, but no driver is available. There is a driver available for Linux, bcwc_pcie, that presumably gets it to function; that would have to be ported.


There are some unmapped addresses by libaml, but I don't know what parsing them will provide functionality for. #P functions are mostly available, with the exception of realmodemem (which is perhaps why VESA doesn't work for the monitor). I haven't really tried any of the other device files yet. /dev/cputemp reports the four CPU temps. aux/acpi produces a bad opcode error from aml, and generates battery and ctl files under /mnt/acpi, yet the battery report is not correct. Fortunately, on my model there's a button the side trim that shows battery status with 8 small leds, but it would be nice to have acpi more functional.


It's recognized as a USB HID device, and mounted with nusb/kb (CSP is 0x000003). I haven't yet tested it out.

Optical drive

The optical drive is recognized and can be mounted and read: use cdfs -d /dev/sdE1, and /mnt/cd will show up (see cdfs man page). You can then eject the optical drive using echo eject >/mnt/cd/ctl.


The audio driver is loaded for intel hd, but there's no audio. I've tried the typical pins that are labeled as speaker and jack, and there's no playback using play(1).


Hopefully this is helpful to anyone else who might be interested in using 9front on an older Macbook. While it was a bumpy road initially, things are starting to smooth out. The main thing for me was being able to use the built-in trackpad and keyboard to work on it without any external peripherals. There are still quite a few things that need to be addressed, but I now have a working setup that meets my immediate needs. See kmesg (the left sidebar) to see what the current boot looks like.