In 2021 I started working on a port of Inferno to the Ben NanoNote. This built upon earlier experiences porting the operating system to a couple of other systems. It was also given a solid foundation thanks to my brother Paul's own experience and knowledge of the NanoNote hardware.
The port of Inferno that got me interested in trying to create my own ports is the inferno-rpi port for the Raspberry Pi. The series of labs that yshurik wrote made it seem possible that I could do something similar. I tried to start my own port to the Gumstix Overo back in 2016, but quickly realised I didn't know enough about the porting process.
In 2018, in an article that covered Limbo, Go and Inferno, I mentioned working on a port of Inferno to the Efika MX Smartbook. This was put on hold for most of the time I was working as a contractor because the work didn't really leave me with enough free time to do anything. However, in mid-2020, when the gig I was doing couldn't pay for full-time work, I got the chance to revisit the port. It continued for a couple of months until the hardware wouldn't boot any more. Until I can find a debug board for it, that port isn't going anywhere.
What inspired me and made me more confident about even continuing the Smartbook port was a brief diversion into retrocomputing and software archaeology. I had seen Rob Pike's ancient e-mail about Inferno On The ARM Processor and had read that there was once a port to Acorn's A7000 computer. The code was no longer present in the Inferno repository, so I thought I could redo it. (Actually, it turned out that the code was present in one of the historical archives, now available in a git repository.) Since the ARM code compilers still had support for ARMv4 targets, it was possible to get something up and running using bits and pieces of other ARM ports, and the A7000+ port was created as a proof of concept, using RPCEmu to test it.
Porting efforts pretty much stopped in late 2020. Then, in 2021, I felt bad about not using the NanoNote that Paul bought for me a number of years ago, and I started wondering what it would take to run Inferno on that.
The NanoNote is built around an Ingenic JZ4720 system on a chip, which contains a processor based on the MIPS32 architecture. With the ARM ports, I felt that I had some passing familiarity with the assembly language code required at the lowest levels of the operating system. MIPS assembly language is quite similar to ARM, being another RISC architecture, but it takes some getting used to. I found that the book, See MIPS Run, helped me gain some familiarity with the workings of MIPS code and the philosophy behind the architecture. Paul also had some hints and tips about writing code for MIPS based on his own experiences.
It's also useful to start from an existing port that uses the same architecture, but there are no MIPS systems in the current Inferno repository. However, Plan 9 does have code for some MIPS platforms, including the routerboard rb450g, which seems to have been developed with Inferno in mind. This at least provides some code to give an idea of what needs to be done to set up an environment for Inferno to run in, such as setting the static base pointer (R30), stack pointer, status register and cause register. It also gives us an insight into how to handle interrupts and exceptions.
Other parts of the hardware also have to be dealt with. The JZ4720 provides a number of peripherals that can be used, and the bootloader sets up some of these for us. So, the framebuffer is ready to use without too much effort, and the keyboard is read using a collection of GPIO pins. Support for reading microSD cards was added after working in parallel on a port of Inferno to the Letux 400 Minibook, and USB peripheral support was added with the aim of making the NanoNote interoperable with desktops and laptops.
USB support is less well-integrated into Inferno than other features, which usually provide their own device files. For example, /dev/backlight can be read and modified to change the screen brightness, /dev/power and /dev/battery provide information about the power button and battery charging state, and /dev/rtc contains the current real time clock value.
Apart from the USB support being a bit unreliable, things work reasonably well. Power cycling after shutdown is a problem, but that should be fixable given that Linux doesn't have any problems with it. Some peripherals, such as those handling audio, aren't supported at all. Others could be enhanced to use DMA.
Some tools and commands are very slow because the JIT compiler has not been enabled. This is mostly because I haven't managed to make floating point exception handling robust enough. For Limbo programs that rely heavily on the built-in C modules, this isn't a huge problem, but more complex Limbo programs suffer from the lack of performance.
Porting Inferno to the NanoNote was interesting, frustrating but rewarding, and will be something that I build on in my diary.
Categories: Inferno, Limbo, Free Software
Copyright © 2022 David Boddie
Published: 2022-01-06 15:14:05 UTC
Last updated: 2022-08-09 16:38:48 UTC