I've been thinking of writing a hobby operating system for some of the ARM processors. There are many popular single-board computers with ARM MPU, so I simply wanted to purchase one of those (choosing one with more open documentation). I was surprised when I found out, that even boards with really enough memory do not have MPUs with Memory Management Unit. As I've always been working with i386+ processors and never anything else (except for some Microchip PICs), I'm now confused and not sure if one can write a working operating system whichs functions wouldn't be limited when comparing to OSes written for MPUs with MMU.  I could think of few solutions for replacing or simulating MMU and I've got few questions:On Intel processors in 16 and 32-bit modes there is a way of using segments and segment selectors to use different blocks of memory by different tasks. That means that I could change memory space by changing contents of segment registers when doing a task switch when on x86. Are there any general concepts for memory segmentation that could be used on ARM architecture?By loading a linked object file instead of executable I could use relocations (fix-ups) or position independent code to point tasks on pieces of memory in the same way as if I mapped the memory using paging structures. Would this be effective enough?I have also read something about Memory Protection Units on ARM processors. Could these be helpful?Are there any usual ways of managing tasks on systems without MMU?
Writing a multitasking operating system for a processor without MMU
operating systems;memory management;memory hardware;os kernel
It's actually not that hard to design an operating system that doesn't require an MMU. There are a few conveniences you'll have to do without, but nothing insurmountable.Since different tasks will have to be loaded at different addresses, all your code (except for the kernel, the standard library, and any other code that's part of your base runtime environment) has to be compiled as position-independent. This means relative jumps and a base address for heap access stored in a register. Spending one register as a base address might seem costly if you're used to x86-32's four general registers, but most modern architectures have more, and even 8088 has the segment registers precisely for that.A Unix-like architecture has to be revised, because you can't implement fork. That's ok, most operating systems don't have fork. (You can have vfork.)You can't preallocate large gobs of space without also allocating the corresponding memory. This means no growing of the stack or heap on the fly by allocating one more page at a time.If you have an MPU, then your tasks can still be separated from each other as usual in multitasking operating systems. Without an MPU, memory separation can only be cooperative if you allow tasks to execute arbitrary code. One way to achieve memory separation without an MPU is to restrict tasks to use only verified code on a virtual machine and implement memory protection in software as part of the VM engine.uClinux is a project based on the Linux kernel that runs on processors (including ARM Cortex-M) without an MMU. Its restrictions on multitasking are essentially what I outlined above.