Running BSD

So, now I had the very first incarnation of Tetris running on my simulated PDP-11. However, it seemed like a bit of a waste: Tetris only required a few tens of K of RAM, while my ESP32 had both its internal RAM as well as 4MiB of PSRAM at its disposal. Why not up the ante a bit and try to run another bit of pioneering software, one that perhaps fit the capabilities of the ESP32 board a bit better?

Another one in a long line of 'first's to run on the PDP11 comes from the Unix world. While Unix itself was not born on the PDP11 (technically, it was born on a borrowed PDP7, even if it got ported to the PDP11 a short while later), the BSD distribution of Unix does originate on the PDP11. You may recognize this as BSD Unix still is around today, in the form of FreeBSD, NetBSD and OpenBSD. It also stands at the roots of more consumer-facing bits of software like Apples iOS and the operating system running on the Playstation line of game consoles.

The other thing that makes BSD attractive is that the most recent version of it (2.11BSD) contains a full TCP/IP networking stack. This stack also is a bit infamous: the earlier versions of Microsoft Windows used to run (bits and pieces of) this stack as well. As IPv4 and and TCP did not change by much since then, this stack should still be operable: I should be able to make this interface with the ESP32s WiFi interface, making this into a truly networked example of BSD running on a PDP11.

Getting BSD to work actually wasn't that hard. Configure a machine that is fast enough, give it an 1.5GiB hard disk (which physically resides on a micro-SD-card slotted into the ESP-Wrover-Kits socket) and enough memory and the physical base on which BSD can run is ready. I did the installation of the OS on the hard disk on my laptop, as the tape drive required to load the installation media for BSD was ripped out of the ESP32 version of SIMH. I then moved the HD image over to my micro-SD-card. I could reuse the 15ИЭ terminal code as it has no issues displaying plain english ASCII either, and the end result was that I could see BSD stating up on my devboard.

However, that only gave me a non-networked version of BSD, as I previously ripped out all of the network interfacing code out of SIMH. (Even if I left it in, ESP-IDF supports none of the interfacing methods it offered, so it would be useless to me anyway.) Luckily, ESP-IDF has a nice and flexible abstraction layer called ESP-NETIF that ties together network interfaces and higher-level things like TCP/IP stacks. I could easily implement a shim there that would take the Ethernet packets coming from the WiFi subsystem and redirect it to SIMH and vice versa. SIMH already contained code to simulate an Ethernet card supported by 2.11BSD, so that should work out nicely.

However, even if the PDP11 is now be able to chuck Ethernet packets directly into the WiFi drivers to send them into the... well... ether, I still didn't have a good solution for network connectivity. First of all, the PDP11 has no notion of WiFi related things like SSIDs and as such. Secondly, DHCP is not a thing in 2.11BSD, and neither is its predecessor BOOTP. I actually thought about porting or implementing a DHCP client, but there's one oddity in the DHCP specs that requires direct access to the network packets, bypassing the TCP/IP layer. The 2.11BSD kernel does not have support for that at all, as far as I can tell. While I'm all for yak shaving, implementing a new kernel interface in a decades-old kernel is a bit too much.

So instead, I decided to abuse the ESP-NETIF layer to make the system have a 'dual personality'. The ESP32 would have a full TCP/IP stack, with the WiFi drivers and a DHCP client. The PDP11 would also have its own BSD TCP/IP stack fully operational. Both stacks would share an IP address, retrieved by the ESP32 software and then passed on to the PDP11. However, a little bit of code would decide to which IP stack to send packets that are received on any of the interfaces. DHCP data from the WiFi interface? Send it to LwIP. Data for a telnet server on the WiFi interface? That's for the PDP11. The code can also interpret some packets coming from the PDP11 all by itself as well. By sending these packets, the PDP11 can scan for WiFi networks, configure WiFi credentials etc. Because the PDP11 can send these packets as standard broadcast UDP packets, there's no need for complicated kernel-level configuration interfaces.

This configuration is done by a little program running on the PDP11: running it allows you to scan for available networks and connect to one. The program will then automatically get the network data from the ESP32 LwIP DHCP client and configure the BSD network interface accordingly. The program is called 'wifid' and, as stated before, it uses broadcast UDP packets that are picked up by the ESP-NETIF shim I wrote. The code outside the emulator picks these up and does the actual work required, sending a response back over UDP broadcast if needed.

I wasn't too eager to write code like this on the ancient C compiler that came with 2.11BSD, but luckily I didn't have to: to my great surprise, even the latest GCC compiler happily supports the PDP11 architecture. Making it link to the BSD binaries was a bit harder and involved some hackery in the form of adding a missing function to the BSD runtime libraries. Also, the header files that came with 2.11BSD use a format that is now rightfully not recognized as valid anymore; instead I patched together an unholy but working mix of RetroBSD headers as well as fixed 2.11BSD ones. The end result is not pretty, but works well enough: I can compile a binary on my laptop, use FTP to send it over to either SIMH running on my laptop or on the ESP32, then succesfully run it there. I guess it's a testament to how beloved the PDP11 is; in the end, it's a 50-year old architecture that commercially died out 30 years ago, but it still has enough fans to send in patches to be officially included and up to date in the current GCC toolchain suite.

After the dust settled, all that was left was a modification or two to the network startup scripts to automatically reconnect the PDP11 to the last-used network when it restarted, and now 2.11BSD is fully capable of connecting to any WiFi network out there.

« Prev 3 Next »

© 2006-2022 Sprite_tm - Contact