Requirements
As there are a lot of potential moving parts, and whole subsystems that aren't directly related to what I'm trying to achieve, I wanted to be clear about how important various features are to me. This then guides my thinking when deciding what to design, what to prototype, and where to compromise.
This takes the form of a MoSCoW breakdown - please expand below to see more...
Must:
- User-level processes can't use resources unless they're explicitly granted access
- Invalid accesses at the very least result in no-op on write, and a dummy value on read
- User-level processes can call specific Supervisor entry points to perform privileged operations in a managed fashion
- e.g. I/O, page allocation, launching other processes
- User-level processes have access to their own stack space and code (obviously)
- User-level processes can (through the Supervisor) request additional memory to be provided
- User-level processes can't escalate their privileges by any means
- Supervisor executes on startup
- Supervisor has access to its own portion of RAM, for stack and data storage
- Supervisor clears RAM pages before assigning them to user processes
- Supervisor can access arbitrary I/O devices attached to the system, e.g. LCD panel, button input, SD card reader, whatever is connected
- Supervisor can read/write video RAM
Should:
- Pre-emptive multitasking system can force normally-running user processes to suspend
- Things like illegal HLT instructions which lock up the CPU may be exceptions to this
- User processes can memory-map video RAM and/or other devices
- User processes have the full 64K address space available
- No address space wasted on things they can't access anyway like ROM or I/O devices
- Trigger errors or process termination on protection violations
- User processes can send RPC requests to each other via the Supervisor
- Interrupts are supported and handled by the Supervisor
Could:
- Abort user processes that aren't responding (e.g. invalid instructions causing HLT)
- This should be possible by resetting the CPU and soft-booting while keeping all the user process state alive
- User processes can agree to share memory
- So they can communicate without going through the Supervisor
- Read-only pages
- Non-executable pages, execute-only pages
- Multithreading
- Most process state is shared but threads have some thread-local storage, including their stack
- Dynamic stack expansion - if a process fills its stack, it gets additional space
- Multi-CPU support
- User processes can request notification of various kinds of interrupt
Won't:
- Virtual memory, i.e. dynamic paging of RAM pages to/from disk, SD card, etc
- It's not specifically related to protection, and there are enough complications that I don't even want to think about it
- Copy-on-write
- Again this kind of requires the ability to pause the CPU while some other system copies the data...