diff options
Diffstat (limited to 'README.md')
| -rw-r--r-- | README.md | 24 |
1 files changed, 22 insertions, 2 deletions
@@ -46,10 +46,30 @@ User loads `C` = syscall number, args in `DE`/`B`, then `rst $30`. Return in `A` | # | name | status | |---|---------|--------| | 0 | exit | ✅ marks zombie, reschedules | +| 1 | fork | ✅ copies the 8 KiB bank, child returns 0 | | 3 | write | ✅ `DE`=buf `B`=len → serial console | | 8 | getpid | ✅ | | 11| yield | ✅ cooperative switch | -| 1,2,4,5,6,7,9,10 | fork/read/open/close/exec/wait/kill/brk | ⛔ `ENOSYS` | +| 2,4,5,6,7,9,10 | read/open/close/exec/wait/kill/brk | ⛔ `ENOSYS` | + +### fork (`sys_fork`, src/proc.asm) + +The interesting syscall. It enters on the parent's user stack (which lives in +the `$A000-$BFFF` cart-RAM window), so before it can swap that window it +**switches to a kernel stack in WRAM0**. Then it: + +1. allocates a free PCB slot + a fresh cart-RAM bank (bump allocator), +2. copies the parent's whole 8 KiB bank → the child bank, 256 bytes at a time + through a WRAM bounce buffer (only one cart-RAM bank is visible at once), +3. plants a **switch-in frame** in the child at `Uafter-8` (`Uafter` = parent + SP at entry): the copied return address is already there, so it just zeroes + the saved `hl/de/bc/af` slots — the child resumes at the post-`fork` PC with + `A=0`, +4. fills the child PCB (shared ROM text bank, new RAM bank, parent as PPID), +5. restores the parent stack and returns the child pid. + +Verified: `init` forks a child (P/C alternate on serial); nested forks yield +three independent processes with distinct pids (`123123...`). ## The context switch (`src/hram.asm`) @@ -91,7 +111,7 @@ A real gbos would render to VRAM; serial is the zero-VRAM debug channel. ## Roadmap -- [ ] `fork`: copy parent's 8 KiB RAM bank → free bank, dup u-area, child returns 0 +- [x] `fork`: copy parent's 8 KiB RAM bank → free bank, child returns 0 - [ ] `exec`: point `PROC_ROMB` at a flashed program, reset RAM-bank layout - [ ] Preemptive scheduling: real context save in `TimerISR` → `hSwitchTo` - [ ] Use the `$D000-$DFFF` u-area (SVBK) for per-process kernel state / kstack |
