boo-os/README.md

178 lines
6.5 KiB
Markdown
Raw Normal View History

2021-11-09 02:19:34 +00:00
# Philosophy of Boo OS
> Operating System: An operating system is a collection of things that don't fit into a language. There shouldn't be one. - [Design Principles Behind Smalltalk](https://www.cs.virginia.edu/~evans/cs655/readings/smalltalk.html)
Boo OS is a meditation on recursive complexity and the curse of simplicity. In an age where computers are so powerful, it is sometimes healing to start again.
I have often been stuck between my desire to build either an operating system, a shell, a language or an ide. None
of those categories ever quite fit the hole I was intending them to fill.
After much introspection and research I finally decided that what I really needed was something different.
Inspired by smalltalk, Boo OS is "image" based, the entire system can be dumped and reloaded to the same state.
Eventually my plan is that Boo OS contain all the essentials necessary for **self modification**. It should be possible to (safely) modify the operating system from within the operating system and have the changes take effect.
How that will look is undecided. For now, Boo OS is coded entirely in Boo Bytecode Assembly Language and assembled
using a Rust based assembler. One of my first targets for a real application is an Assembler written in Boo Bytecode,
run on BooOS and outputting a Boo Bytecode image.
## BooVM
Boo OS is written in Boo Bytecode which is run by the Boo Virtual Machine (BooVM). BooVM and Boo Bytecode is inspired
by various retro computing architectures with minimal instructions, but a focus on integrating with the core
systems.
As such. the BooVM offers minimal integration with the outside world. Interaction is limited to:
- Reading and Writing BooVM images to/from the Host OS
- Exposing The State of the Keyboard and Mouse
- Offering a Framebuffer for Display Output
- (Provisional) Reading and Writing "Files" from the Host OS OR Loading and Interacting with a generalized
File System that can be loaded by both operating systems (i.e. some kind of virtual disk image)
### Why Write a Custom VM?
Why Not? This is a meditation on recursive complexity. I was already set on writing a new language and building one from the ground up on a custom instruction set seemed like a great idea.
The longer version is that I looked into many options for the base of this project. They fell into
two main categories:
The first featured existing ISA emulations (e.g. QEMU) and existing production ready language virtual machines (e.g. JVM, Lua) - I decided that using an existing architecture wasn't in the spirit of the project. Further, both of these options
would require extra work to integrate a framebuffer display and input up to the extent where I would be writing an OS
for an existing architecture. I wanted to keep the wrapping interface to the host OS as simple as possible.
The second category featured older reto architectures, emulators and the like. I rejected this approach because
there are some details I don't want to care about, like scanlines and cartridge layouts. This approach would also
make interaction with the Host OS a project in itself likely requiring forking and significant rework resulting in
a custom emulator any way.
After research, designing and implementing an assembler for some custom bytecode and building a small VM to run
it seemed to be the simplest option and provides me with a lot of freedom moving forward, and lends itself to
infinite experimentation.
## TODO List
The below represents some ideas for projects to tackle within Boo OS.
- [x] Print Strings to the FrameBuffer
- [x] Set Framebuffer Position Helper Function
- [x] `put_char` Helper Function
- [ ] Memory Management
- [ ] Heap Design
- [ ] Implement Helper Functions `alloc` and `free`
- [ ] Memory Safety
- [ ] Keyboard Input
- [ ] Designing Input Interaction (poll v.s. interrupts)
- [ ] Create a Console Shell to Interact with the System
- [ ] At first this shell will be limited to pre-programmed commands
- [ ] But, it should quickly all the construction of new commands from old ones
- [ ] Finally, the shell should facilitate saving and loading of images
- [ ] Write a Bootstrapped Assembler Application in Boo Bytecode Assembly
# Formal Reqs
Run time:
- Memory needs R/W/E flags - 3 bits
- Mapping Memory before handing off to lesser privileged processes
- Needs some understanding off operating mode
- Never attempt to pop an empty stack
Memory
We treat each 64 chunks of memory as a single page:
0x0000 4800 Pages of Write only Display Memory
0x4B000 1 Page of Registers [rip, mode, display, rax, r2, r3, r4, r5, r6, r7, r8]
0x4B040 1 Page of Call Stack
0x4B080 1 Page of Input Flags (Keys Down etc)
0x4B0C0 Dynamic Memory Begins
## Instructions
All instructions are fixed length.
## Meta Instructions
0x00 - Nop
0x01 - Update Display
0x0F - HLT
## Dynamic Instructions
Prefix 0x1#,0x2#,0x3# are given to dynamin register based commands
- 0x1n STORE(n) $Addr (R(n)) -> Addr)
- 0x2n LOAD(n) $Addr (Addr -> R(n))
- 0x3n LOADI(n) IMM (Immediate -> R(n))
- 0x4n INC(n)
- 0x5n DEC(n)
- 0x6n ISTORE(n)
- 0x7n x LDSTORE Load the Address Stored in n into reg(x)
- 0x8n x Transfer R(n) to R(x)
- 0x9n Shift
## Arithmetic
Prefix 0xa# is given to arithmetic functions
- 0xa1 ADD (R2 + R3 -> RAX)
- 0xa2 SUB (R2 - R3 -> RAX)
- 0xa3 MUL (R2 * R3 -> RAX)
- 0xa4 DIV (R2 / R3 -> RAX)
- 0xa5 SHIFT (R2 >> R3 -> RAX)
- 0xa6 AND (R2 & R3 -> RAX)
# Stack
Prefix 0xc# allows call stack manipulation. The machine denotes 64 memory addresses at memoo
- 0xc0 RET
- 0xc1 PUSH Call Stack
# Jumps and Branches (0x5#)
- 0xE0 JMP $Addr - Unconditional jump to $Addr
- 0xE1 JMPEQ $Addr (if R1 == R2 jmp $Addr else )
- 0xE2 JMPNEQ $Addr (if R1 != R2 jmp $Addr else )
- 0xE3 JMPGT $Addr (if R1 > R2 jmp $Addr else )
- 0xE4 JMPLT $Addr (if R1 < R2 jmp $Addr else )
- 0xE5 JMPGEQ $Addr (if R1 >= R2 jmp $Addr else )
- 0xE6 JMPLEQ $Addr (if R1 <= R2 jmp $Addr else )
## Admin Mode Instructions
Instructions prefixed with 0xF are admin instructions
- 0xF0 UNSET_R $Addr (Sets the 64 addresses after $Addr as Not Readable)
- 0xF1 SET_R $Addr (Sets the 64 addresses after $Addr as Readable)
- 0xF2 UNSET_W $Addr (Sets the 64 addresses after $Addr as Not Writable)
- 0xF3 SET_W $Addr (Sets the 64 addresses after $Addr as Writable)
- 0xF4 UNSET_X $Addr (Sets the 64 addresses after $Addr as Not Executable)
- 0xF5 SET_X $Addr (Sets the 64 addresses after $Addr as Executable)
- 0xFF DROP_MODE $Addr - Drops from Admin Mode into User Mode (No access to Admin mode instructions)
0: LOAD_IMM 10
1: NOP
2: DEC(1)
3: JNEQ
##