193 lines
9.8 KiB
Markdown
193 lines
9.8 KiB
Markdown
# Python on danos: the milestone plan
|
||
|
||
The execution plan for [python-on-danos.md](python-on-danos.md). That note holds
|
||
the *why* and the design decisions; this one slices the work into milestones with
|
||
concrete deliverables, tests, and exit criteria. Milestones are numbered **P0–P5**
|
||
(track-local — the global M-series stays with the driver/lifecycle tracks).
|
||
|
||
Dependencies at a glance:
|
||
|
||
```
|
||
P0 toolchain + mini-libc ──┐
|
||
P1 streams + console + seam ─┴─→ P2 CPython minimal ─→ P3 terminal + REPL
|
||
│ │
|
||
└─→ P4 danos module │
|
||
+ Python service│
|
||
P5 process control + shell ←─────────────────────────────────┘
|
||
```
|
||
|
||
P0 and P1 are independent of each other and can proceed in parallel. P1 is shared
|
||
work — it is also Zig self-hosting Phase 1 and the first three slices of
|
||
[character-devices-and-tty.md](character-devices-and-tty.md).
|
||
|
||
## P0 — Toolchain + the C library compatibility layer
|
||
|
||
**Goal:** a C hello-world, cross-compiled on the host with `zig cc`, runs on danos.
|
||
|
||
Design and slicing live in
|
||
[c-library-compatibility.md](c-library-compatibility.md): the **libdanos-c**
|
||
sysroot (hand-written danos-native headers + `libc.a`) as a `library/c/` build
|
||
package — pure computation (string, libm, `strtod`, the printf/scanf engines)
|
||
lifted from a vendored, pinned musl subtree; the OS plumbing written in Zig over
|
||
the `runtime` surface (re-targeting `runtime.os` when the Zig track authors it);
|
||
`malloc` over danos `mmap`; a `crt0` bridging the danos entry shim to C `main`.
|
||
Driven by `zig cc -target x86_64-freestanding-none -isystem` (the triple becomes
|
||
`x86_64-danos` if the Zig fork lands first; nothing else changes).
|
||
|
||
Its five slices (sysroot-skeleton, fd-plumbing, malloc, stdio,
|
||
mathematics-and-time) carry their own tests — host-side oracle suites for the
|
||
computation layer, QEMU cases (`c-hello`, `c-file-io`, `c-stdio`, `c-time`) for
|
||
the plumbing.
|
||
|
||
**Exit:** `c-hello` and `c-file-io` green in the QEMU suite; host computation
|
||
tests green.
|
||
|
||
## P1 — Stream nodes, console, and the seam pieces
|
||
|
||
**Goal:** the shared Phase-1 surface exists: byte-stream stdio, cwd, environment,
|
||
entropy. Design and slicing live in
|
||
[character-devices-and-tty.md](character-devices-and-tty.md); this milestone is
|
||
its slices 1–3 plus three small seam pieces:
|
||
|
||
- **cwd/chdir** — per-process current directory used by path resolution (the
|
||
kernel already anchors a VFS root per `fs_resolve`; the cwd is the same idea,
|
||
process-scoped, with `getcwd`/`chdir` exposed through `runtime` and the libc).
|
||
- **Environment** — spawn carries an environment block; the SysV entry stack's
|
||
`envp` slot ([sysv.md](os-development/sysv.md)) stops being empty; `getenv`
|
||
reads it. An empty block stays valid.
|
||
- **Entropy** — a kernel `entropy` syscall (RDSEED/RDRAND with a jitter fallback,
|
||
mirroring the TSC-reliability posture of not trusting one CPU feature blindly);
|
||
the libc exposes `getentropy`.
|
||
|
||
- **Tests.** QEMU: the character-device tests from the tty note (offsetless
|
||
read/write, blocking read, cooked/raw control round-trip), plus `cwd-basics`
|
||
(chdir + relative open), `env-roundtrip` (spawn with env, child reads it),
|
||
`entropy-sane` (nonzero, changing, correct length).
|
||
|
||
**Exit:** a C program reads a cooked line from fd 0 and echoes it to fd 1 —
|
||
injected key events in, bytes read back through the console's in-memory sink,
|
||
all under QEMU with no hardware involved — and `getcwd`/`getenv`/`getentropy`
|
||
return real answers.
|
||
|
||
## P2 — CPython, minimal configuration
|
||
|
||
**Goal:** `python -c 'print(2**100)'` runs on danos under QEMU.
|
||
|
||
- Pin **CPython 3.13.x**; vendor as `third-party/cpython/` or fetch via the build
|
||
(decide with the build-packages conventions).
|
||
- Host build-Python of the same version (`--with-build-python`).
|
||
- `config.site` cache for the cross answers; `config.sub` patch so
|
||
`x86_64-unknown-danos` parses; a small `configure`/`pyconfig` patch set kept as
|
||
rebasable diffs, WASI-style.
|
||
- `--disable-shared`; static `Modules/Setup`: `posix errno _io _codecs _weakref
|
||
time math _stat _collections itertools _functools _locale _sre` plus what the
|
||
interpreter core insists on; threadless build (WASI precedent).
|
||
- `Lib/` on the FAT image under the hierarchy (e.g. `/system/python/lib`);
|
||
`PYTHONHOME` set accordingly; `.pyc` written with **checked-hash
|
||
invalidation** (FAT's 2-second mtime granularity makes mtime-based validation
|
||
lie during fast edit-run cycles).
|
||
- `PYTHONHASHSEED` pinned only if P1's entropy slipped — otherwise real
|
||
hash randomization from day one.
|
||
- **Tests.** QEMU: `python-expr` (the exit criterion), `python-file` (run a
|
||
script from FAT, write a file, read it back), then a curated slice of CPython's
|
||
own suite (`test_int`, `test_float`, `test_io`, `test_dict`) as a
|
||
longer-running target — the suite is the porting harness.
|
||
|
||
**Exit:** the four QEMU cases green; the CPython test slice green or with a
|
||
short, documented skip list.
|
||
|
||
## P3 — Terminal + REPL: the first real application
|
||
|
||
**Goal:** an interactive `python` REPL in a graphical danos terminal — the
|
||
milestone demo for the OS.
|
||
|
||
- Depends on the display track's font rendering (its stated next step) — until
|
||
that lands, the REPL is exercised end-to-end through the pseudo-device
|
||
harness from P1+P2 (scripted input in, output read back), so P2's exit is
|
||
never blocked on graphics; the graphical terminal is the *interactive* debut.
|
||
- The terminal application: draws with the UI toolkit / display client, consumes
|
||
keyboard `InputEvent`s, and — per the tty note's load-bearing decision —
|
||
**serves the VFS stream protocol itself** to its children, reusing the console's
|
||
line-discipline library. Spawns `python` with its endpoints as fd 0/1/2.
|
||
- Raw mode + the control set give the REPL line editing; window-size control
|
||
gives it wrapping.
|
||
- **Tests.** QEMU: scripted terminal session (inject key events, assert rendered
|
||
or captured output). Real-hardware smoke on the Intel box joins the existing
|
||
checklist.
|
||
|
||
**Exit:** typing `2+2` into the terminal on the QEMU GPU target prints `4`.
|
||
|
||
## P4 — The `danos` extension module + a Python service
|
||
|
||
**Goal:** Python can speak danos: IPC, capabilities, spawn.
|
||
|
||
- The `danos` module, **written in Zig against `Python.h`**, statically linked
|
||
via `Modules/Setup`: endpoints (create/send/receive), capability passing,
|
||
spawn + exit-notification, and the service bootstrap (announce, supervision
|
||
handshake) — the same surface Zig services use, re-exposed.
|
||
- UI-toolkit bindings as a second module once the toolkit's API settles.
|
||
- Prototype **one real service in Python** — policy-shaped, not data-plane
|
||
(candidates: hot-plug policy, a settings service) — speaking an existing wire
|
||
protocol, supervised by the device manager like any service.
|
||
- **Tests.** QEMU: `python-ipc-echo` (Python service echoes over an endpoint, a
|
||
Zig client asserts), plus the prototype service's own protocol test.
|
||
|
||
**Exit:** a Python process runs as a supervised danos service exchanging IPC
|
||
with Zig peers.
|
||
|
||
## P5 — Process control, then the shell
|
||
|
||
**Goal:** danos can spawn arbitrary programs with arguments and pipes; a small
|
||
Python shell uses it.
|
||
|
||
The kernel/VFS cluster a shell forces (any shell, any language):
|
||
|
||
- **exec-of-path** — spawn an arbitrary VFS path, not a named ramdisk binary;
|
||
- **argv/envp** — carried through spawn onto the child's entry stack (env from
|
||
P1, argv new);
|
||
- **numeric exit status** — extend the exit record beyond the categorical
|
||
`ExitReason` (the gotcha the Zig roadmap flagged: `WEXITSTATUS` must be real);
|
||
- **fd inheritance + pipes** — a kernel or service pipe (a character device by
|
||
the tty note's definition) and spawn-time fd mapping.
|
||
|
||
Then, in order: `subprocess` enabled in CPython (maps onto spawn + the
|
||
exit-notification endpoint — no fork, Windows-style); a **small Python shell** (a
|
||
few hundred lines over `subprocess` + the console: prompt, argv parsing, pipes,
|
||
cwd) as the forcing function that reveals what job control actually needs.
|
||
|
||
**Explicitly deferred past P5:** the pthread subset over `thread_spawn`/futex,
|
||
signals-in-libc via M17, termios job control (Ctrl-C to foreground child), and
|
||
**xonsh** — which wants all three and is the arc's endpoint, not a milestone.
|
||
|
||
**Tests.** QEMU: `spawn-argv-exit` (child echoes argv, exits 42, parent sees
|
||
42), `pipe-through` (parent → child → parent), `python-subprocess`, and a
|
||
scripted shell session.
|
||
|
||
**Exit:** the Python shell runs `program | program` typed at the terminal and
|
||
reports the exit status.
|
||
|
||
## Post-P5 outlook
|
||
|
||
Two tracks continue past this plan, each with its own design doc rather than a
|
||
P-number here:
|
||
|
||
- **Dynamic libraries** ([dynamic-libraries.md](dynamic-libraries.md), D1–D4) —
|
||
an application-layer facility (the OS stays static and lean): `dlopen` in the
|
||
libc, then libffi + `ctypes` + loadable extension modules, then shared
|
||
read-only mappings so N Python services hold one physical `libpython`.
|
||
- **The full C compatibility layer**
|
||
([c-library-compatibility.md](c-library-compatibility.md), stages 2–3) — the
|
||
standing rule that every system capability ships with its C spelling, draining
|
||
the absence table toward "portable C builds on danos"; `fork` is the one
|
||
permanent exception.
|
||
|
||
## Related
|
||
|
||
- [python-on-danos.md](python-on-danos.md) — the design note this executes.
|
||
- [c-library-compatibility.md](c-library-compatibility.md) — P0's design.
|
||
- [character-devices-and-tty.md](character-devices-and-tty.md) — P1's design.
|
||
- [zig-self-hosting.md](zig-self-hosting.md) — shares P1; its fork makes P0's
|
||
triple prettier but gates nothing here.
|
||
- [os-development/process-management.md](os-development/process-management.md) —
|
||
the spawn/exit surface P5 extends.
|