memory: schinit and the BIOS/UEFI split
This commit is contained in:
parent
baede13847
commit
64aa13886d
3 changed files with 102 additions and 0 deletions
63
.claude/memory/schos-schinit.md
Normal file
63
.claude/memory/schos-schinit.md
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
---
|
||||
name: schos-schinit
|
||||
description: "schinit is process 1, launchd-shaped; job manifests, the ControllingTerminal trap, and what milestones 2 and 3 are"
|
||||
metadata:
|
||||
node_type: memory
|
||||
type: project
|
||||
originSessionId: 9d8a2aef-bcf0-47a0-96c6-f706efab4a95
|
||||
modified: 2026-08-09T14:36:32.587Z
|
||||
---
|
||||
|
||||
**`cmd/schinit/` is process 1**, chosen by Nexoniarz to be "close to Apple's
|
||||
launchd, the king of inits". `lib/initcode.S` execs `/bin/schinit`. The old
|
||||
`cmd/init` is still in the tree but nothing runs it.
|
||||
|
||||
**Milestone 1 (done, 2026-08-09):** manifests, `RunAtLoad`, `KeepAlive` with
|
||||
`ThrottleInterval`, reaping, `ControllingTerminal`.
|
||||
**Milestone 2:** socket activation — schinit holds the listener and starts the
|
||||
job on first connect. `[Socket name]` / `Path` is already parsed and stored in
|
||||
`job.sock_path`, so manifests do not have to change.
|
||||
**Milestone 3:** `schinitctl` (list/start/stop/reload), `WatchPaths`, per-user
|
||||
agents.
|
||||
|
||||
**The format is sectioned `key = value`**, not plists. Decided deliberately:
|
||||
the roadmap's own words are that "the point of copying launchd rather than
|
||||
sysvinit is not the config format, it is *demand launching*". Keys keep
|
||||
launchd's names so the model transfers. Files live in `etc/schinit/*.job` in the
|
||||
repo and are installed to `/etc/schinit/` by the `etc-install` target — **not
|
||||
written straight into `sysroot/`, which is gitignored**; that is why a fresh
|
||||
clone has no `/etc/passwd` or `/etc/motd` (still an open gap).
|
||||
|
||||
**No libc in `cmd/`.** These programs link `lib/` — raw syscall stubs. No
|
||||
malloc, no printf, no strlen. Static storage and hand-rolled helpers only.
|
||||
|
||||
**`getdents64` was exposed for this.** The kernel has had syscall 96/217 since
|
||||
the Linux ABI landed, but nothing declared it in `include/user.h` or
|
||||
`lib/usys.S`, so first-party programs could not list a directory at all. Step
|
||||
records by `d_reclen`, never `sizeof`.
|
||||
|
||||
## The trap worth remembering: setsid() costs you the terminal
|
||||
|
||||
`setsid()` puts a job in its own session, and **a new session has no controlling
|
||||
terminal**. The console delivers input only to the foreground process group it
|
||||
tracks (`tty_fg_pgrp`), so the shell started, echoed every keystroke through the
|
||||
line discipline, and executed nothing. It looks exactly like a hung shell and is
|
||||
really a terminal that is not listening to it. See
|
||||
[[schunix-tty-fg-pgrp-coupling]].
|
||||
|
||||
`ControllingTerminal = yes` claims it in the child: `ioctl(0, TIOCSCTTY, 0)`
|
||||
then `ioctl(0, TIOCSPGRP, &pg)` where `pg = getpid()` (after `setsid()`, pgid ==
|
||||
pid). **Off by default** — a daemon has no business seizing the console.
|
||||
`TIOCSCTTY` is currently a no-op in the kernel; `TIOCSPGRP` does the real work.
|
||||
|
||||
## Do not transcribe bootstrap() from memory
|
||||
|
||||
The first version dropped `/dev/input/event0-1` and most of `/proc`, because it
|
||||
was copied from the part of the old `cmd/init/main.c` that had been read on
|
||||
screen rather than all 124 lines. `-Evdev` caught it with
|
||||
`inputtest: cannot open /dev/input/event0`. **Read the whole file before
|
||||
replacing it.**
|
||||
|
||||
Also: `build/usbstick.img` must be built by `all`. Without it QEMU refuses the
|
||||
`-drive` and the entire `-Usb` run produces no output — which reads as a broken
|
||||
USB driver, not a missing file.
|
||||
Loading…
Reference in a new issue