universalisos/.zcode/plans/plan-sess_ffb410a7-2f49-438d-850c-0f71dba55428.md

19 KiB

Plan: Replicate the full PikeOS src/bin toolchain in pure Rust

Lane discipline

This work is in the mycelium tooling lane at /home/fabiorafaelcoutada/portugalfuturista/mycelium/. It does not edit anything in /home/fabiorafaelcoutada/portugalfuturista/universalisos/src/bin/ or universalisos/src/sources/. The user explicitly requested "no connection or API for pikeos" — so the result is a 1:1 cargo binary per PikeOS tool, with clean Rust names (not pikeos-configconv, but configconv). PikeOS's src/bin/ is left untouched; what we ship is a replacement toolkit the integrator can opt into.

Scope (per the user's "100% feature parity, every PikeOS-named tool" + "no PikeOS connection")

We replicate every PikeOS tool that exists in universalisos/src/bin/ (excluding the standard Linux utilities that aren't PikeOS-proprietary). For each one we ship a separate cargo binary under portugalfuturista/mycelium/crates/ that takes the same arguments and produces the same output as the PikeOS tool — but in pure Rust, on top of the mycelium xsd, model, codegen, xml, and adt-kdev crates.

The bash wrappers in universalisos/src/bin/ stay where they are; if the user wants the universalisos build to use the Rust tools, the wrappers can be edited in a separate step. The point of this work is the Rust toolkit itself.

Categorisation of the 60+ entries in universalisos/src/bin/

Per the survey, the 60+ entries break into four buckets:

Bucket Treatment Count
A. Standard Linux utilities (leave alone — already real) No work; they're already real ELFs. 11: cfs-tool, dtbtool, dtc, gen_eth_addr, img2srec, make, mkblkimage, mkbootimg, mkimage, mkisofs, mtools (+ 5 symlinks).
B. 0-byte PikeOS stubs (real binary elsewhere in the PikeOS distro) Replace with our Rust crate. 6: pikeos-configconv, muxa, xorriso (the symlink target), FormatXML.jar, ProjectConfiguratorNX.jar, PikeosTraceControl.jar.
C. PikeOS-proprietary ELFs (replaceable) One Rust crate each, 1:1. 9: pikeos-configmore, pikeos-make-cat, pikeos-multi-romimage, pikeos-romdump, pikeos-vmit-dump, pikeos-recovertablesort, pikeos-xml-edit, pikeos-xsd-string, pikeos-gentd (Python).
D. Bash wrappers around Java JARs / Perl / shell Two options per wrapper (see below). ~17: pikeos-cloneproject, pikeos-format-xml, pikeos-upgrade-project, pikeos-upgrade-source, pikeos-check-init, pikeos-makeboot, pikeos-build-recipe, pikeos-traceheadergenerator, pikeos-info, pikeos-validate-xml, pikeos-control, pikeos-tracecontrol, pikeos-realpath, pikeos-version, pikeos-rpm, pikeos-rpm2cpio, pikeos-get-cdk, pikeos-share-project, pikeos-var-rewrite, mcomp, killmuxa, pikeos-projectconfigurator.

For the bash wrappers (D), the survey shows they all do one of three things:

  1. Call a real PikeOS ELF / JAR that we're replicating in C (→ re-implement the bash as a wrapper that execs our Rust binary).
  2. Call a standard Linux tool with a PikeOS-specific argument translation (→ bash is fine; just rewrite the wrapper to call the same Linux tool).
  3. Format a PikeOS XML file in a particular way (→ bash using xmllint is sufficient).

For the 0-byte stubs (B), the existing PikeOS binary simply doesn't exist on this system. The user's intent is that our Rust replacement is the new authoritative implementation. We'll ship each as a proper Rust crate, and the corresponding PikeOS name in src/bin/ becomes a symlink to the new binary if the user wants the kernel build to use it (but the symlink itself is not part of this commit).

File layout

/home/fabiorafaelcoutada/portugalfuturista/mycelium/
├── crates/
│   ├── mycelium-xsd/         # (existing) XSD + confxsd annotation parser
│   ├── mycelium-model/       # (existing) resolved IR
│   ├── mycelium-codegen/     # (existing) emitters (header, binary, asm-enum, crc, test-inc)
│   ├── mycelium-cli/         # (existing) configconv --enum --struct --bin --crc --enum-asm --test
│   ├── mycelium-tfw/         # (existing) TFW C test harness from <tc> XML
│   ├── mycelium-xml/         # (NEW, ~600 LoC) the mycelium-xml crate: a thin Rust XML utility that the new tools share
│   ├── configmore/           # (NEW, ~1.2k LoC) pikeos-configmore equivalent
│   ├── make-cat/             # (NEW, ~500 LoC) pikeos-make-cat equivalent
│   ├── xsd-string/            # (NEW, ~400 LoC) pikeos-xsd-string equivalent
│   ├── vmit-dump/            # (NEW, ~700 LoC) pikeos-vmit-dump equivalent
│   ├── romdump/              # (NEW, ~700 LoC) pikeos-romdump equivalent
│   ├── multi-romimage/       # (NEW, ~400 LoC) pikeos-multi-romimage equivalent
│   ├── recovertablesort/     # (NEW, ~300 LoC) pikeos-recovertablesort equivalent
│   ├── xml-edit/             # (NEW, ~600 LoC) pikeos-xml-edit equivalent (sysgo:m4 namespace)
│   ├── gentd/                # (NEW, ~500 LoC) pikeos-gentd equivalent (Python→Rust)
│   ├── validate-xml/         # (NEW, ~200 LoC) pikeos-validate-xml equivalent (reuses mycelium-xsd)
│   ├── format-xml/           # (NEW, ~150 LoC) pikeos-format-xml equivalent (xmllint wrapper)
│   ├── share-project/        # (NEW, ~300 LoC) pikeos-share-project equivalent
│   ├── clone-project/        # (NEW, ~200 LoC) pikeos-clone-project equivalent (reuses share-project)
│   ├── upgrade-project/      # (NEW, ~400 LoC) pikeos-upgrade-project equivalent
│   ├── upgrade-source/       # (NEW, ~300 LoC) pikeos-upgrade-source equivalent (renames sed-regex)
│   ├── build-recipe/         # (NEW, ~300 LoC) pikeos-build-recipe equivalent
│   ├── makeboot/             # (NEW, ~200 LoC) pikeos-makeboot equivalent (sources bs.*)
│   ├── check-init/           # (NEW, ~300 LoC) pikeos-check-init equivalent (parses objdump -rt)
│   ├── var-rewrite/          # (NEW, ~250 LoC) pikeos-var-rewrite equivalent (template engine)
│   ├── projectconfigurator/  # (NEW, ~600 LoC) pikeos-projectconfigurator equivalent
│   ├── control/              # (NEW, ~500 LoC) pikeos-control equivalent (interactive)
│   ├── info/                 # (NEW, ~250 LoC) pikeos-info equivalent
│   ├── version/              # (NEW, ~150 LoC) pikeos-version equivalent
│   ├── get-cdk/              # (NEW, ~150 LoC) pikeos-get-cdk equivalent
│   ├── realpath/             # (NEW, ~100 LoC) pikeos-realpath equivalent
│   ├── traceheadergenerator/ # (NEW, ~400 LoC) pikeos-traceheadergenerator equivalent (reuses mycelium-tfw)
│   ├── tracecontrol/         # (NEW, ~500 LoC) pikeos-tracecontrol equivalent
│   ├── mcomp/                # (NEW, ~100 LoC) mcomp equivalent
│   ├── killmuxa/             # (NEW, ~100 LoC) killmuxa equivalent
│   ├── muxa/                 # (NEW, ~600 LoC) muxa host equivalent
│   └── xorriso/              # (NEW: this is the Linux `xorriso`; not PikeOS. We symlink. No new Rust crate.)
├── docs/
│   ├── CONFIGCONV_CONTRACT.md   # (existing) configconv CLI contract
│   ├── ANNOTATION_VOCAB.md      # (existing) cx: directive catalogue
│   ├── PIKEOSTOOLS_INDEX.md     # (NEW) a single doc indexing every tool, its PikeOS equivalent, its crate, and its CLI matrix
│   └── TOOL_CONTRACTS/          # (NEW) one per-tool CLI contract
│       ├── configmore.md
│       ├── make-cat.md
│       ├── xsd-string.md
│       ├── vmit-dump.md
│       ├── romdump.md
│       ├── multi-romimage.md
│       ├── recovertablesort.md
│       ├── xml-edit.md
│       ├── gentd.md
│       ├── validate-xml.md
│       ├── format-xml.md
│       ├── projectconfigurator.md
│       ├── control.md
│       ├── info.md
│       ├── version.md
│       ├── share-project.md
│       ├── clone-project.md
│       ├── upgrade-project.md
│       ├── upgrade-source.md
│       ├── build-recipe.md
│       ├── makeboot.md
│       ├── check-init.md
│       ├── var-rewrite.md
│       ├── get-cdk.md
│       ├── realpath.md
│       ├── traceheadergenerator.md
│       ├── tracecontrol.md
│       ├── mcomp.md
│       ├── killmuxa.md
│       └── muxa.md
├── conformance/                  # (existing) round-trip fixtures
└── adt/                          # (existing) PikeOS ADT replica

Total: ~30 new crates, ~12k LoC of Rust (excluding tests and docs).

A mycelium-xml shared crate (NEW foundation)

Several of the new tools need to read and write PikeOS-flavored XML (the sysgo:m4 namespace, the <x:set> / <x:delete> / <x:merge> directives, project.xml etc.). The current mycelium-codegen has a tiny read_xml_instance for the offline-test round-trip; that's not enough. The new mycelium-xml crate (~600 LoC) provides:

  • An XML tree model with namespace support (the existing Rust xml-rs crate would do).
  • A round-trip pretty-printer.
  • Helpers for the sysgo: and sysgo:m4 namespace handlers.
  • A replace_all-style search/replace for the pikeos-upgrade-source renames.

mycelium-xml is a workspace dependency for: xml-edit, upgrade-source, share-project, clone-project, upgrade-project, format-xml, projectconfigurator, makeboot, var-rewrite, check-init, gentd, traceheadergenerator, info, version.

Per-tool implementation plan (grouped by build path vs. IDE/integrator)

Group 1 — kernel build path (highest priority)

The universalisos kernel build actually invokes these. Until this group is done, make -C src/sources/ukernel-arm_v7hf cannot rely on the Rust toolchain (it works today because the pre-generated headers are committed, but a fresh XSD change requires these).

  1. configmore — the pikeos-configmore companion. Already partially done in mycelium --test (the .inc generator). Add a mycelium configmore subcommand with the full PikeOS surface: configmore [-test] [-in-place] [--inspect] [--dump] [-xml] [-X] <input>... per the PikeOS user manual. Use mycelium-codegen for the .inc output and a new binary-dump module for the textual dump. (~1.2k LoC)
  2. make-catpikeos-make-cat <share/xsd dir> > catalog.xml. Walk the dir for .xsd files, parse each one's targetNamespace, emit OASIS catalog entries. Reuses mycelium-xsd to extract the namespace. (~500 LoC)
  3. xsd-stringpikeos-xsd-string <file.xsd> — serialise an XSD to a canonical, byte-identical C string. Used by the %.csd: %.xsd rule in src/target/arm/v7hf/makeinc/rules.mk. Implementation: re-parse the XSD with our parser, normalise whitespace, output. (~400 LoC)
  4. validate-xmlpikeos-validate-xml <xml> <xsd>... — validate an XML against one or more XSDs. Reuses mycelium-xsd::parse_schema (already validates) + a thin quick-xml-based XML-schema validator. (~200 LoC)
  5. format-xmlpikeos-format-xml <file> — pretty-print a PikeOS XML file. Thin wrapper around xmllint --format (the FormatXML.jar PikeOS uses does the same). (~150 LoC)
  6. vmit-dumppikeos-vmit-dump <vmit.bin> — dump a vmit.mod binary in textual form. Reuses the adt-kdev types and mycelium-codegen::emit_binary (in reverse) to parse the blob, then a print module produces the begin_toplevel / end_toplevel text format. (~700 LoC)
  7. romdumppikeos-romdump <rom.bin> — same shape as vmit-dump but for ROM images (which use a different header format). (~700 LoC)
  8. multi-romimagepikeos-multi-romimage <rom1> <rom2>... <out> — concatenate multiple ROM images into one, computing the relocation table. Uses adt-kdev for the binary layout. (~400 LoC)
  9. recovertablesortpikeos-recovertablesort <input> — sort the cross-reference relocation table for --bin output. Small helper. (~300 LoC)
  10. xml-editpikeos-xml-edit --in-place --fix-layout ... — apply sysgo:m4 namespace transformations (<x:set>, <x:delete>, <x:merge>, <x:include>, <x:define>). Reuses mycelium-xml for the I/O. (~600 LoC)
  11. gentdpikeos-gentd <td.xml> — auto-assign EventId / SubEventId / FilterBit to a trace definition file. The current PikeOS is a Python script; we re-implement in Rust on top of mycelium-xml. (~500 LoC)

Group 2 — integration / host build (medium priority)

These are invoked by p4ext/recipe files and integration projects, not the kernel build itself. Same 1:1 replication.

  1. projectconfiguratorpikeos-projectconfigurator (the 0-byte stub for ProjectConfiguratorNX.jar). Replicate the CLI: --init, --export, --import, --get, --set. (~600 LoC)
  2. share-project / clone-project — export/import/clone a project skeleton (CRLF, init, rebase). Share most logic; one has the project init. (~500 LoC combined)
  3. upgrade-project — migrate a project.xml to a newer schema version. (~400 LoC)
  4. upgrade-source — apply rename regexes (p4_P4_, vm_VM_, drv_DRV_) to a directory of C sources. Perl-replacement. (~300 LoC)
  5. build-recipe — iterate build_flavors VAR=VAL matrices; for each variant, run configure + make. (~300 LoC)
  6. makeboot — board-specific boot-image preparation; sources bs.* from share/boot/. (~200 LoC)
  7. check-init — parse objdump -rt from stdin; warn on cross-section calls into .xtext.init. (~300 LoC)
  8. var-rewrite{{VAR}} / {{FOREACH}} template engine for PikeOS build system. (~250 LoC)
  9. info — report installed CDKs, PSPs, service releases, license info. Reads a manifest file the integrator provides. (~250 LoC)
  10. version — print installed PikeOS version summary. (~150 LoC)
  11. get-cdkpikeos-get-cdk --list. Thin wrapper over info. (~150 LoC)
  12. realpathpikeos-realpath. Thin wrapper over readlink -m. (~100 LoC)

Group 3 — interactive / runtime (lowest priority)

  1. control — interactive control panel (PikeOS's PikeosControl.jar JLine UI). Replicate the command surface (not the Swing UI; this is a CLI). (~500 LoC)
  2. traceheadergenerator — generate the trace header C from a .td.xml. Reuses mycelium-tfw (we have it). (~400 LoC)
  3. tracecontrol — interactive trace-streaming control. Reuses muxa. (~500 LoC)
  4. mcompmcomp <file-in-image> <host-file> — compare a file in a FAT image to a host file. Thin wrapper over mtools's mcopy. (~100 LoC)
  5. killmuxa — list/kill running MUXA host processes. POSIX-sh replacement. (~100 LoC)
  6. muxa — host-side MUXA serial multiplexer server. Replaces a 0-byte stub. (~600 LoC)

Open gaps inherited from earlier iterations

Several of the new tools (configmore .inc, vmit-dump, romdump) depend on the struct-aware binary format that the previous iteration listed as an open gap. The new tools will read existing PikeOS-format binaries, so they need the inverse of the current emitter — i.e. a mycelium-binary parser module. That parser is a prerequisite for vmit-dump and romdump, and reuses adt-kdev for the header types.

To keep the scope tight, I'll add a single new crate mycelium-binary (separate from mycelium-codegen to avoid coupling) that handles:

  • drv_config_header_t parsing.
  • Recursive struct parsing (offsets, alignment, ID/IDREF cross-ref).
  • Trailing alignment handling.

This is ~500 LoC of Rust and is the inverse of the current emit_binary. Once this exists, vmit-dump and romdump are mostly printing.

Test strategy

For each new tool, write three tests:

  1. CLI surface test — argument parsing matches PikeOS's documented flags (parse the PikeOS user manual, encode it as a set of test cases).
  2. Round-trip test — for configmore: take a real PikeOS binary, run the Rust configmore on it, compare output. For make-cat: take a real XSD directory, compare generated catalog to PikeOS's. For gentd: compare a fresh gentd output to a checked-in golden.
  3. Property test for the mycelium-xml shared crate: round-trip arbitrary XML through it and check that read-then-write is the identity.

Where possible, reuse the existing conformance/ fixtures. The conformance/offline-test/ fixture is already a PikeOS fixture we can drive the new tools against.

For tools that don't have a PikeOS-testable input (e.g. muxa is runtime-only), unit-test the internal state machine and provide a cargo run --example demo.

Documentation

  • docs/PIKEOSTOOLS_INDEX.md — a single page listing every tool, its PikeOS equivalent, our crate name, the CLI matrix (what flags we honour), and the test status.
  • docs/TOOL_CONTRACTS/<tool>.md — one per-tool CLI contract (the same shape as CONFIGCONV_CONTRACT.md for configconv).
  • The per-crate README.md includes a "PikeOS compatibility" section listing the per-flag differences (so a user can find at a glance which flag of the original PikeOS tool we don't yet support).

Build & run

# All crates share a workspace
cd /home/fabiorafaelcoutada/portugalfuturista/mycelium
cargo build --release

# Each tool is its own binary
./target/release/configmore --help
./target/release/make-cat /opt/.../share/xsd > /tmp/catalog.xml
./target/release/vmit-dump ./vmit.bin
./target/release/xml-edit --in-place project.xml
...

# All tests
cargo test                            # 11+ existing + ~60 new tests
cargo test -p configmore               # per-tool suite
cargo test -p make-cat
...

Iteration order

This is a multi-iteration effort. To keep each iteration bounded and reviewable, I'll sequence:

  1. Iteration A (this plan, Group 1 first): mycelium-xml shared crate + the 11 build-path tools (configmore, make-cat, xsd-string, validate-xml, format-xml, vmit-dump, romdump, multi-romimage, recovertablesort, xml-edit, gentd) + the mycelium-binary parser. Result: the make -C src/sources/ukernel-arm_v7hf path can be driven end-to-end by the Rust toolchain.
  2. Iteration B (Group 2): the 12 integration tools (projectconfigurator, share-project, clone-project, upgrade-project, upgrade-source, build-recipe, makeboot, check-init, var-rewrite, info, version, get-cdk, realpath).
  3. Iteration C (Group 3): the 6 interactive/runtime tools (control, traceheadergenerator, tracecontrol, mcomp, killmuxa, muxa).

Each iteration ends with: all workspace tests green, the iteration's tools documented in docs/TOOL_CONTRACTS/, and the iteration's scope indexed in docs/PIKEOSTOOLS_INDEX.md. Commits are per-tool or per-group (3-5 commits per iteration).

Lane boundary

  • I do not touch universalisos/src/bin/. The PikeOS-named scripts and JARs in that directory stay where they are. If the user wants the universalisos kernel build to use the Rust toolchain, that's a separate step (editing the bash wrappers, or adding symlinks).
  • I do not touch universalisos/src/sources/ukernel-*/Makefile* or xsdgen/*. The CLI compatibility is what makes the kernel build work without changes.
  • I do not add any PikeOS-name aliases. The user explicitly requested "no connection or API for pikeos" — every binary is named cleanly (configmore, not pikeos-configmore).