- Update Makefile for new source files - Fix include paths - Update kernel docs
6.2 KiB
UniversalisOS KDEV Provider Framework (armv7/core)
PikeOS kdev_prov.c replica: the provider half of the kdev driver/provider
split, complementing the driver half in core/uos_kdev.{h,cpp} (kdev_drv.c).
Why it exists
The original uos_kdev framework is a driver registry: each driver
self-registers into .uos_drv and carries its own init/open/close/.... There
was no class-level provider owning a pool of device instances with
reference-counted open/close — the PikeOS pattern where a shared device
(console, pci-mgr, clock) is set up once on first open and torn down on last
close. This adds that half without disturbing the existing driver registry.
What's implemented
.uos_provlinker section (armv7linker.ld) parallel to.uos_drv.uos_prov_desc_t { name, prov_id, *ops, max_dev }+UOS_PROV_REGISTER(name, &desc)macro placing a pointer in.uos_prov.uos_prov_ops_t { init, open, close, read, write, ioctl }— class hooks, any member may be NULL.- Discovery:
uos_kdev_prov_init_all()(walk + callinit),uos_kdev_prov_ find(prov_id),uos_kdev_prov_count(). - Refcounted instances: a static table (
UOS_KDEV_MAX_INSTANCES=16) keyed by(prov_id, dev_id).uos_kdev_open()binds on first open (calls provideropen) and bumps on later opens;uos_kdev_close()decrements and calls the providercloseteardown exactly once on the last close, then frees the slot. Return codes:-1unknown provider,-2dev_id out of range,-3table full,-4provider open failed,-5close underflow/not-open. - Built-in
consoleprovider (UOS_PROV_ID_CONSOLE=5) as a worked example with a functionalwritepath. uos_kdev_prov_demo()prints[kdev-prov] OKafter asserting all semantics.
Wiring / gotcha
kernel.cpp calls uos_kdev_prov_demo() immediately after
uos_cfg_materialize() and before uos_cfg_run_guests(). The later D-3..D-5
cluster (IRQ/Time/KDEV-driver/VFP/SMP) sits past uos_cfg_run_guests(), which
does not return to the linear sequence on the current armv7 boot path — so the
pre-existing KDEV driver demo is also not reached there. If run_guests is ever
made to return, move the provider demo back into that cluster next to the driver
demo.
riscv/aarch64 are unaffected: they compile core via the core-objs-y allowlist
(empty), so uos_kdev_prov.cpp is armv7-only, and the .uos_prov section only
exists in the armv7 linker script.
Verification (ad-hoc, not suite green)
- Banned-token scrub (
p4_/P4_) on the new files: 0. make ARCH=armv7 PLATFORM=qemu-arm-virtclean build + QEMU boot →[kdev-prov] OKwith: registered=1, init "console", find(CONSOLE) FOUND, open(CONSOLE,1)= rc2 (range), openx2 refcount=2 open_calls=1, closex2 refcount 2->1->0 close_calls=1, close(underflow)=rc5, console write ok. No aborts/panic.- Non-regression: aarch64-linux + aarch64-classic builds clean.
Boot-verification caveat (2026-07-13): the ARMv7 link/boot is currently blocked by an unrelated, in-progress concurrent session — a new
kernel/src/core/arch_init.h(x86_64 bring-up header) collides by filename witharch/armv7/inc/arch_init.hon the-Isrc/coreinclude path, andkernel.cppnow referencesarch_exceptions_init/arch_initthat ARMv7 does not define yet. The PROV-2 compile units (uos_kdev_prov.cpp,cfg_parser.cpp) build clean; the failure is entirely in the concurrent session'sarch_*symbols. Per the parity ledger these files are off-limits, so boot verification of PROV-2 must wait until that header collision is resolved (e.g. rename the x86_64 header tocore/arch_init_x86_64.hor gate it byARCH).
Open items
- PROV-2: DONE — the active instance-pool cap is now config-driven via the
UniversalisOS manifest lane instead of the hardcoded
UOS_KDEV_MAX_INSTANCES:system_model.kdev_max_instances(sysmodel.h) carries the cap; it defaults toUOS_CFG_KDEV_MAX_INSTANCES_DFLT(16) and is overridden by a top-level<KdevProviderTable MaxInstances="N"/>element in the embedded manifest (boot-simple.xml, parsed by cfg_parser.cpp).UOS_KDEV_MAX_INSTANCESis now the static allocation bound (64, the freestanding hard max for the instance table); the active cap is clamped to it viauos_kdev_prov_configure()/uos_kdev_prov_apply_config(), which the demo calls before exercising the pool.inst_find/inst_allocare bounded by the active cap, not the hard max.boot-simple.xmlexercises this with<KdevProviderTable MaxInstances="8"/>; the demo printspool cap = 8 (alloc bound 64)and the CFG banner printskdev provider pool cap=8.- The original "mycelium codegen" framing is the follow-on: mycelium can later
emit the same
MaxInstancesvalue into the generated manifest; the kernel consumes it identically through the existing parser. No kernel build dependency on mycelium was introduced (the kernel embeds boot-simple.xml directly via cfg_blob.S).
- PROV-3: DONE — per-instance
read/write/ioctlrouting helpers (uos_kdev_read/uos_kdev_write/uos_kdev_ioctl) mirror open/close and return-5(not open) /-1(unsupported) appropriately; exercised by the console write and clock read in the demo.
Files
kernel/src/core/uos_kdev_prov.h— provider descriptor, ops, register macro, open/close/refcount API, read/write/ioctl routing, demo prototype.kernel/src/core/uos_kdev_prov.cpp— section walk, instance table, refcounted open/close, console + clock providers,[kdev-prov] OKdemo.kernel/src/arch/armv7/linker.ld—.uos_provsection in thedataPHDR.kernel/src/core/kernel.cpp—uos_kdev_prov_demo()call site (live path, beforeuos_cfg_run_guests()).kernel/src/core/config/sysmodel.h—kdev_max_instancesfield +UOS_CFG_KDEV_MAX_INSTANCES_DFLTdefault.kernel/src/core/config/cfg_parser.cpp—<KdevProviderTable MaxInstances>handler + manifest default + CFG banner line.kernel/src/core/config/boot-simple.xml—<KdevProviderTable MaxInstances="8"/>.kernel/src/core/uos_time.cpp— ARMv7 backend ofuos_arch_time_now()/uos_arch_time_freq()(CNTPCT physical counter), the missing P-1 deliverable that the clock provider depends on.