178 lines
6.5 KiB
Markdown
178 lines
6.5 KiB
Markdown
|
# 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
|
||
|
|
||
|
|
||
|
##
|