diff options
| author | user <user@clank> | 2026-07-16 00:04:09 +0200 |
|---|---|---|
| committer | user <user@clank> | 2026-07-16 00:04:09 +0200 |
| commit | 0a77a11e17f697bf797655c4ae87b927432b1f88 (patch) | |
| tree | 97cafaa103aec412f692daff9e068fc63f0496bf /README.md | |
| parent | kernel: implement fork() (diff) | |
| download | gbos-0a77a11e17f697bf797655c4ae87b927432b1f88.tar.gz gbos-0a77a11e17f697bf797655c4ae87b927432b1f88.tar.xz gbos-0a77a11e17f697bf797655c4ae87b927432b1f88.zip | |
kernel: implement exec()
- sys_exec(B=program id): look up ProgramTable, point PROC_ROMB at the program's
ROM text bank, map it into $4000-$7FFF, reset stack, jp to entry (no return)
- programs.asm: two demo programs (ping/pong) ORG'd at the SAME $4000 in banks
2 and 3 - proves execution is driven purely by PROC_ROMB
- demo: init forks; parent execs PROG_PING (bank2, '1'), child execs PROG_PONG
(bank3, '2') -> '1212...', 2000/2000 balanced, zero garbage
- README: document exec + text-in-ROM model
Diffstat (limited to 'README.md')
| -rw-r--r-- | README.md | 23 |
1 files changed, 21 insertions, 2 deletions
@@ -48,9 +48,27 @@ User loads `C` = syscall number, args in `DE`/`B`, then `rst $30`. Return in `A` | 0 | exit | ✅ marks zombie, reschedules | | 1 | fork | ✅ copies the 8 KiB bank, child returns 0 | | 3 | write | ✅ `DE`=buf `B`=len → serial console | +| 6 | exec | ✅ `B`=program id → maps ROM text bank, jumps in | | 8 | getpid | ✅ | | 11| yield | ✅ cooperative switch | -| 2,4,5,6,7,9,10 | read/open/close/exec/wait/kill/brk | ⛔ `ENOSYS` | +| 2,4,5,7,9,10 | read/open/close/wait/kill/brk | ⛔ `ENOSYS` | + +### exec (`sys_exec`, src/proc.asm + programs.asm) + +Where the text-in-ROM model pays off. Programs are linked to run from the ROMX +window (`$4000-$7FFF`) and stored in their own ROM banks (`programs.asm`). +`exec(B=program id)`: + +1. looks up `ProgramTable[B]` = (ROM bank, entry), +2. sets `PROC_ROMB` and maps the bank live into `$4000-$7FFF`, +3. resets the stack to the top of the task's (already mapped) cart-RAM bank, +4. `jp`s to the entry — it never returns. + +Proof it's really bank-driven: both demo programs are ORG'd at the **same** +address `$4000` in **different** banks (02 and 03). The parent `exec`s +`PROG_PING`, the child `exec`s `PROG_PONG`, and the output `1212...` (2000/2000, +zero garbage) can only happen if each process executes its own bank via +`PROC_ROMB`. A fuller exec would also copy `.data` from ROM and zero `.bss`. ### fork (`sys_fork`, src/proc.asm) @@ -112,7 +130,8 @@ A real gbos would render to VRAM; serial is the zero-VRAM debug channel. ## Roadmap - [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 +- [x] `exec`: point `PROC_ROMB` at a program in a ROM bank, reset stack, enter +- [ ] `exec` refinement: copy `.data` from ROM + zero `.bss` for RW globals - [ ] Preemptive scheduling: real context save in `TimerISR` → `hSwitchTo` - [ ] Use the `$D000-$DFFF` u-area (SVBK) for per-process kernel state / kstack - [ ] `brk`/heap allocator inside the task bank (heap up, stack down, collision = ENOMEM) |
