Hacker News new | past | comments | ask | show | jobs | submit login
RetroBSD: Unix for microcontrollers (retrobsd.org)
263 points by fanf2 on June 15, 2018 | hide | past | favorite | 54 comments

Pretty cool.

Made me wonder if it would make sense on these SoC targets to dynamically load a program from external storage and write into internal flash for execution, then start running it without a reboot.

Since such flashes are typically only erasable in pretty big blocks ("sectors") it would require some interesting design choices, but it should be doable. :)

There are several runtimes for microcontrollers that feature an elf/hex loader for static binaries, or a bootloader that retrieves a program and executes it in RAM. Sometimes you can re-enter the bootloader from your application software. On some embedded systems (satellite OBSW comes to mind) you can actually hot-patch the code function-by-function while running. You compile/link the software with some extra space before and after your functions for future modifications. Then when you patch, you have to make sure that the modified code is locked out and that the variables used by the functions being patched are in an acceptable state as well as the cache. Whether all of that extra effort makes sense? - it depends. But in most embedded projects you can just flash a new firmware and avoid the overhead of executing from RAM. (Depending on your target, flash might have a separate memory bus and could be one or two clock cycles faster.)

Edit: Hot-patching in flash is totally possible as well.

Sounds interesting - any runtimes in particular you could point out? Interested to read more about them.

I built such a system for a PIC32 in a previous job.

When it was online, we'd connect to it over Ethernet and send it firmware updates that it would burn to an external SPI flash chip (we used it for testing communications protocols with a wide variety of products, and it needed frequent firmware updates). If one of these updates had a bug and bricked the controller, it was a hassle (not to mention downtime!) to remove it from the machines on the production floor and bring it back to engineering to plug in the dedicated programming device.

So we set up the SPI flash to store two copies of the firmware. If it went down, you could reset it while holding down a "restore last-known-good firmware" button, and the boot routine would reflash the on-board flash memory with the previous copy of the firmware from the SPI flash.

I wouldn't do this every time you needed to power cycle it - but on a per-revision level it was very useful!

I'd be hesitant, as those flash banks aren't rated for more than 1000 or so writes over their lifetime. I've killed the internal flash in a few Arduinos and STM32s just from development/testing.

Hm. Makes me think how many (few) bytes you could fit a "if a specific interrupt is received then copy bytes from wire to RAM and run that instead" preamble into the bootloader.

Presuming "killed" means "won't accept new updates but will read" (?), you could then continue to use the chip.

> Made me wonder if it would make sense on these SoC targets to dynamically load a program from external storage and write into internal flash for execution, then start running it without a reboot.

There is less reason for this today because high-capacity, high write-count storage is cheap. But I have seen it done, e.g. in order to retrofit redundant firmware update schemes on devices that do not originally support it. A long time ago I looked into something like this for one of the devices I was working on at the time (the firmware was stored in the internal flash of the MCU, but was steadily growing, and we'd eventually run out of space to hold two copies; however, we also had a larger, cheaper, slower external flash that we could use).

The write cycles cap of flash devices can make it a bad idea under some scenarios, but that's a decision you make on a case-by-case basis. ZOMG THIS IS FLASH DO NOT REWRITE IT is not exactly a clever design solution.

Integrated NOR flash still commonly tops out at 100K erases. Not something you'd want to be doing as an integral part of an OS execution model.

You could exec from SRAM if you have enough to spare (larger Cortex M4/M7 uCs have 256k+, RetroBSD claims to only need 128k of that).

Yes, of course, I've done that.

It was the idea of treating on-board flash as a load-target for temporary programs that felt fun.

This is, essentially, what the older generation of “flash carts” for game consoles do. Each new loaded game ROM gives you a progress bar as the cart performs an erase/program cycle to its flash. (The newer generation just copies the ROM to memory.)

Some of these SoC targets (like the STM32F4x9 series) have SDRAM controllers so you can put 4 - 16MB of RAM on them.

As interesting as this is, I'm not really sure what this gets you over a regular RTOS that might be used with these sorts of microcontrollers apart from easy porting of existing unix software (though with 2.2BSD it would have to be very restricted in its use of syscalls - does it even have sockets?)

I have this running on a Fubarino. It's nice to fiddle with but not quite useful to be serious. I have an ethernet module that at some point I need to hook up to it.

What I really want is a DIP version of the PIC32 with enough RAM and flash to run this or the 4.4-based LiteBSD[1] by the same people.

[1] - https://github.com/sergev/LiteBSD

I wonder why there's no port for the ESP32 boards family. Plenty of RAM/Flash (compared to PIC32), lots of I/O ports and peripherals and built in WiFi/BT. It just seems to me the perfect target, or am I missing something? https://en.wikipedia.org/wiki/ESP32

I think its because the PIC32 uses the MIPS 4k CPU architecture which a compiler that can build this RetroBSD exists for. I'm not sure what kind of CPU architecture the ESP32 uses-- I think its some proprietary DSP core.


For most compilers: xtensa-esp32-elf will work, so long as the ESP-IDF toolchain is available.

Agreed, If I could get 4M(16bit) or 16M/32M/64M and a tty going, and some tiny ssh implementation+ethernet that would be amazing.

Why dip?

Easy to solder?

Exactly. I build projects in my spare time to teach people how to solder. SOIC or QFN is just about doable for beginners, but having a full Unix computer that anyone can build in an afternoon would be pretty cool.

PIC32 is one of the the most underestimated MCU architectures; you get a small powerful computer for a fraction of the cost of one. I think it's doomed because of Cortex-M, but what you can do with it in that price range still amazes me. If only the Chinese picked it up... The boards by Olimex are nice to work with but could be a bit cheaper.

If you want to checkout a POSIX RTOS for microcontrollers, I would checkout Nuttx. I have built some commercial products with it.

[0] nuttx.org

The hardware looks pretty limited right now, but I have to wonder if this can be used as a base for replacing closed source Lights out Management such as iLO, DRAC, and LoM

Interesting idea; but this is 2.11BSD, not OpenBSD, so the attack surface/weak links are mostly unknown for this majorly obscure kernel configuration/port.

IMO I'd generally want OOB management kit to be Very Very™ secure, and especially if it lets me near any secure boot keys. In any case this kind of thing will categorically have the ability to reboot the system, so if I can tinker with configuration I definitely want to have some degree of confidence in the auth process etc.

Completely outside the scope of a microcontroller, what would a reasonable 10-year target for video capture be within a "server console/admin" context? 1080p? 2K? DisplayPort? HDMI? (Obviously VGA)

I'm guessing HDMI and maybe 2K. Hm.

> 2.11BSD, not OpenBSD, so the attack surface/weak links are mostly unknown for this majorly obscure kernel configuration/port.

They're actually probably pretty well known for most things, just buried under decades of literature and commits.

Starting off with a 4BSD would probably be better though since 32bit vax bsd unix got a lot more traction (and more direct code lineage to the modern ports).

But yes, if going 32bit with enough ram, might as well just port OpenBSD/NetBSD and get on with it.

Any idea what the minimum RAM requirements of something like Open or NetBSD is?

I know that modern FreeBSD can boot to a single user process with something like 32M RAM on 32-bit systems with a very stripped down kernel configuration. 64M gives a little more breathing room. But those are both many orders of magnitude larger than 128kB.

It wouldn't surprise me if OBSD or NBSD can fit in a little less RAM, but it also wouldn't surprise me if they still need at least a handful of MB, i.e., 32-64x Retro's 128 kB.

> I know that modern FreeBSD can bootI to a single user process with something like 32M RAM on 32-bit systems with a very stripped down kernel configuration.

Wow! My first BSD box (386BSD) had 8 megabytes of RAM and that was plenty! You could even compile moderately large programs without any swapping. But then, feeping creaturism has always been a BSD tradition! :)

> But then, feeping creaturism has always been a BSD tradition! :)

In general, living software adapts to the constraints of the hardware developers use and care about. The most visible case of this is probably web browsers (and web sites).

If BSD developers were interested in a minimal memory configuration, they could make it happen. It just hasn't been anyone's priority, and machines have many orders of magnitude more RAM today than they did in ~1992.

My comment was not intended as criticism, but merely as an "oh, look how times have changed!". If anything, it was intended as an expression of affection. I have used BSD ever since as my only OS.

That being said, software development in general is in a desolate state these days with unnecessary layers of abstraction and bloat all over the place. The featurism of ancient BSD looks pretty harmless today.

Serial is still the best server console. Especially if you seperately have power control and a way to hit the drop to debugger interrupt.

Agreed. There would be a ton of work to sift through that and using a modern BSD may likely be a better path forward. I just think it’s very interesting in how small a space this runs.

Your other question is also a good one. I couldn’t hazard a guess what the next 10 years for video would be. I would guess display port in some format, but VGA is still kicking around a lot. For *nix serial still works quite well.

HDMI-over-IP is something you can just buy off Amazon for a few hundred dollars?

Yes but you have to check what you buy carefully.

There are HDMI over cat5/6 cable that are basically point to point and are basically just replacing the cable to transmit a longer distance.

The more expensive products that claim to translate HDMI into IP and send over an ethernet network. I'm not sure if they are just turning into ethernet packets and only work on a LAN or if they turn into routable IP packets.

Worst case you need to teach the router to create a Layer2 VPN. It's doable.

The cases:

- HDMI-over-IP-over-Ethernet-over-cat5 (best case)

- HDMI-over-Ethernet-over-cat5

- HDMI-over-cat5 (worst case)

If Ethernet (layer 2) isn't somewhere in there, you're not going to be able to set up a layer 2 network for it.

Well sure. I guess I should be more specific, but the points was that as long as it works in a local Ethernet network, you are fine, as you can fix it reasonably easy by just encapsulating packets. And as long as you don't encrypt, you don't even need much/expensive hardware to handle e.g. 10 Gb/s Ethernet over an IP network.

If you just have a passive thing that translates HDMI connectors to RJ-45 connectors, Ethernet won't help you. But if you use Ethernet, you can also use IP. That is all.

BMCs are now powerful enough to run full Linux/BSD and there's a distro for them: https://github.com/openbmc/openbmc

Thank you, I hadn’t heard d of this yet.

This can be pretty interesting for inexpensive IoT and IIoT devices.

No, this is jut a toy, it would never be used for real IoT or IIoT devices.

There is no need to dynamically load any code on these type of devices, you would generally just use eXecute-In-Place (XIP). The type of applications you develop for these devices simply do not require UNIX like features (multi-user, etc). Many more appropriate OS'es exist for this to be taken seriously.

> No, this is jut a toy, it would never be used for real IoT or IIoT devices.

There's lots of outrageous stuff inside today's consumer products. What makes you so sure that this won't be used in a real (whatever that means) IoT or IIoT device by someone?

Because I design this sort of stuff for a living and have done for over twenty years. As a realistic product solution, this has no benefits over existing widely supported solutions that are more targeted at this level of device.

For example... it can work in 128KB RAM. If you're using 128KB just to run the OS, thats completely wasted RAM that could be used by your application. This really counts when you're making 100'000 of these devices and are paying for every byte. You don't waste valuable resources on desktop-level abstractions. That would make for a very expensive product.

Many people might think you're talking figuratively about paying for every byte. I'll add for others that 8-16-bit MCU's still sell billions of dollars of volume specifically to increase profit per unit by using tinier, cheaper chips. Likewise, stuff like eCos lets you include just the software you need in the RTOS to further shave off ROM or RAM needs. This helps per unit since suppliers often charge extra for extra RAM/ROM on a specific chip. Finally, reliability and security can improve a bit by simply having less software or hardware to screw up.

I think this implementation is intended as a toy or proof of concept, maybe something like this could be used but I doubt this specific one would ever be used in a product. Seems like a lot of overhead for a single-purpose microcontroller. PIC32 is also not a super popular architecture, especially not in Asia (not saying it's bad, just that ARM has pretty much won that fight already). I'm not a super expert on that sort of thing, but casually I can't remember ever seeing a PIC32 in the wild.

I am not saying it's a good idea, but you have Minix (multi-user Unix, it can even compile itself) in (all?) Intel 64 bit chipsets.

This comment is misinformed. Unix has always been multi user, and has always (aside from earliest days before anyone heard of it) been able to compile itself. Minix does not stand for multi-user Unix.



The reference is presumably to Intel's use of Minix in its CPUs - see, e.g., https://www.zdnet.com/article/minix-intels-hidden-in-chip-op... - as an example of a place where a multi-user OS (that can compile itself...) might be used for what might seem like an embedded-type application.

There already exist a number of more suitable operating systems for these purposes that require much less resources e.g. NuttX, RIOT, Contiki, Zephyr. Running this requires at least 128k of SRAM and 512k of flash just for the OS, so you're looking at the expensive end of the uC range to begin with.

Also there's FreeRTOS: https://freertos.org/

Yes, I didn't include it as it's not well suited to IoT "out of the box" due to lack of wireless drivers, and very limited network stack. I do enjoy it's simplicity and have used it for many non-networked projects (the Hungarian notation is brain damaged though :().

A FreeRTOS with that stuff on a popular board sounds like a good project or business opportunity if Wittenstein isnt on it already. ;)


There are a number of real-time executives and operating systems that provide a POSIX API and are mostly compliant as far as sensible or feasible on such devices, for example RTEMS and RIOT-OS.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact