diff options
| author | user <user@clank> | 2026-07-16 11:10:45 +0200 |
|---|---|---|
| committer | user <user@clank> | 2026-07-16 11:10:45 +0200 |
| commit | 2d3597c3a02f821bb364b8ecc23fc5949fca738d (patch) | |
| tree | 714cc7463eb36306f44fcfd67fcf52de0c13b3d1 /src/syscall.asm | |
| parent | shell: I/O redirection (>/<) and pipes (|); rewrite shell in C (diff) | |
| download | gbos-2d3597c3a02f821bb364b8ecc23fc5949fca738d.tar.gz gbos-2d3597c3a02f821bb364b8ecc23fc5949fca738d.tar.xz gbos-2d3597c3a02f821bb364b8ecc23fc5949fca738d.zip | |
kill + ps: implement SYS_KILL (pid 1 immortal) and a ps tool
- PCB gains PROC_PROG (running program id), set by exec, inherited on fork.
- sys_kill(pid): reject pid 1 (immortal) and unknown/dead pids; mark the target
zombie, reparent its children to init, wake its parent if blocked in wait;
schedule away if a process kills itself. Reuses FindPcbByPid/ReparentToInit.
- sys_ps(slot,buf)->{pid,state,prog}; sys_progname(id) via NameTable reverse
lookup. NameTable gains sh/ps/kill.
- libc: kill/psget/progname; tools ps (pid state cmd) and kill <pid>.
- verified: ps lists sh(B)+ps(R); kill 1 refused; kill 42 fails.
Diffstat (limited to '')
| -rw-r--r-- | src/syscall.asm | 168 |
1 files changed, 167 insertions, 1 deletions
diff --git a/src/syscall.asm b/src/syscall.asm index f149a76..0b47c05 100644 --- a/src/syscall.asm +++ b/src/syscall.asm @@ -43,7 +43,7 @@ SyscallTable: dw sys_exec ; 6 EXEC dw sys_wait ; 7 WAIT dw sys_getpid ; 8 GETPID - dw sys_nosys ; 9 KILL (TODO) + dw sys_kill ; 9 KILL dw sys_nosys ; 10 BRK (TODO) dw sys_yield ; 11 YIELD dw sys_getb ; 12 GETB @@ -54,6 +54,8 @@ SyscallTable: dw sys_setin ; 17 SETIN dw sys_setout ; 18 SETOUT dw sys_lookup ; 19 LOOKUP + dw sys_ps ; 20 PS + dw sys_progname ; 21 PROGNAME ; ----------------------------------------------------------------------------- sys_nosys: @@ -388,3 +390,167 @@ sys_wait: .nochild ld a, $FF ret + +; ============================================================================= +; sys_kill(B = pid) -> A = 0 ok / $FF fail. pid 1 (init/shell) is immortal. +; Terminates the target: mark zombie, reparent its children to init, wake its +; parent if blocked in wait. If we killed ourselves, schedule away forever. +; ============================================================================= +sys_kill:: + ld a, b + cp INIT_PID + jr z, .fail ; init is immortal + call FindPcbByPid ; A=pid -> DE=&PCB, CF if not found (B preserved=pid) + jr c, .fail + ld a, [de] ; state + cp PS_FREE + jr z, .fail + cp PS_ZOMBIE + jr z, .fail ; already dead + ; mark ZOMBIE + ld a, PS_ZOMBIE + ld [de], a + ; PROC_EXIT = KILL_CODE + ld a, e + add PROC_EXIT + ld l, a + ld a, d + adc 0 + ld h, a + ld a, KILL_CODE + ld [hl], a + ; victim's parent pid + ld a, e + add PROC_PARENT + ld l, a + ld a, d + adc 0 + ld h, a + ld a, [hl] + ld [wKillParent], a + ; reparent victim's children to init (B still = victim pid) + ld a, b + ld [wExitMyPid], a + call ReparentToInit + ; wake victim's parent if it is blocked in wait() + ld a, [wKillParent] + call FindPcbByPid + jr c, .maybe_self + ld a, [de] + cp PS_BLOCKED + jr nz, .maybe_self + ld a, PS_READY + ld [de], a +.maybe_self + ; if the victim is the current process, don't return to it + ld a, [wCurProc] + add PROC_PID + ld l, a + ld a, [wCurProc+1] + adc 0 + ld h, a + ld a, [wExitMyPid] + cp [hl] + jr nz, .ok +.dead + call SchedYield + jr .dead +.ok + xor a + ret +.fail + ld a, $FF + ret + +; ============================================================================= +; sys_ps(B = slot, DE = buf[3]) -> A = 1 if used (buf = pid,state,prog), else 0 +; ============================================================================= +sys_ps:: + ld a, e + ld [wPsBuf], a + ld a, d + ld [wPsBuf+1], a + ld a, b + cp MAX_PROCS + jr nc, .no + call PcbPtr ; DE = &PCB[slot] + ld a, [de] ; state + cp PS_FREE + jr z, .no + ld a, [wPsBuf] + ld l, a + ld a, [wPsBuf+1] + ld h, a ; HL = buf + push de ; PCB + ld a, e + add PROC_PID + ld e, a + ld a, d + adc 0 + ld d, a + ld a, [de] ; pid + ld [hl+], a + pop de + push de + ld a, [de] ; state + ld [hl+], a + pop de + ld a, e + add PROC_PROG + ld e, a + ld a, d + adc 0 + ld d, a + ld a, [de] ; prog id + ld [hl], a + ld a, 1 + ret +.no + xor a + ret + +; ============================================================================= +; sys_progname(B = id, DE = namebuf) - copy the command name for a program id. +; ============================================================================= +sys_progname:: + ld hl, NameTable +.l + ld a, [hl] + or a + jr z, .none + ld a, l + ld [wPnStart], a + ld a, h + ld [wPnStart+1], a +.sk + ld a, [hl+] + or a + jr nz, .sk ; HL now at the id byte + ld a, [hl] + cp b + jr z, .match + inc hl ; skip id -> next entry + jr .l +.match + ld a, [wPnStart] + ld l, a + ld a, [wPnStart+1] + ld h, a + ld b, 8 +.cp + ld a, [hl+] + ld [de], a + inc de + or a + jr z, .done + dec b + jr nz, .cp +.done + ret +.none + ld a, $3F ; '?' + ld [de], a + inc de + xor a + ld [de], a + ret |
