- Rust 99.5%
- Linker Script 0.5%
| .github | ||
| src | ||
| .editorconfig | ||
| .gitignore | ||
| .markdownlint-cli2.yaml | ||
| ARCHITECTURE.md | ||
| Cargo.toml | ||
| CODE_OF_CONDUCT.md | ||
| CONTRIBUTING.md | ||
| LICENSE | ||
| linker-deviced.ld | ||
| linker-phase2-driver-capcheck.ld | ||
| linker-phase2-driver-hold.ld | ||
| linker.ld | ||
| README.md | ||
| ROADMAP.md | ||
| rustfmt.toml | ||
| SECURITY.md | ||
deviced
deviced is the device manager daemon for EriX.
EriX is a clean-room, capability-based microkernel operating system written entirely in Rust.
Technical requirements are tracked in the EriX requirements, conventions, and project documentation.
See:
- docs for design documents, specifications, and development plans.
- Related architecture repositories for kernel, services, libraries, drivers, and integration tooling.
Purpose of This Repository
This repository implements the EriX device service daemon. Its purpose in EriX is to provide the device service role through explicit IPC and startup authority.
Functionally, it implements the daemon runtime, state model, IPC handling, and validation tests. The repository keeps the implementation, interface contracts, tests, and documentation for that behavior in one reviewable ownership boundary.
The maintained responsibilities are:
- implement the device service runtime and state model
- validate startup authority before accepting IPC requests
- handle bounded service operations through the assigned endpoint set
- keep service behavior, tests, and authority invariants documented
Clean-Room Policy
EriX follows a strict clean-room philosophy:
- No external source code may be copied.
- No external Rust crates are allowed.
- No code generation tools that embed third-party code.
- All code must be authored within the project.
Violations will result in rejection of the contribution.
License
All EriX repositories are licensed under the ISC License.
Development Model
EriX development is modular, deterministic, reproducible, authority-explicit, security-first, and self-hosting oriented.
This repository follows the project roadmap and the validation rules documented in its own roadmap.
Runtime model
- Registry state:
unsealed->sealed. - BootConfig is parsed by
rootd;devicedremains BootConfig-agnostic and receives lifecycle intent only through RPCs. - Seed operation is idempotent for exact tuple matches.
- Drivers are not auto-started at seal/startup.
- Seeded bindings for non-service-managed driver roles are rejected. Current
supported
drv-*roles are all expected to beprocd-managed. - The internal phase2 fixture drivers used by the device-manager-only scenario
are seeded as already discovered so that start/stop verification can run
without bringing up the separate probe/hotplug stack. Those fixture bindings
do not inherit auto-start activation flags, so runtime reconciliation cannot
spawn them behind
rootd's explicit lifecycle checks. - Activation is reconciled from:
- discovery state (
REPORT_DEVICE,REPORT_HOTPLUG) - HAL readiness (
REGISTER_HAL) - provider visibility (
REGISTER_PROVIDER)
- discovery state (
drv-serialkeepsSERIALDas the consumer-scoping role for provider resolution, but driver process startup itself no longer waits for theREGISTER_HALround trip; that avoids a circular boot dependency while preserving the explicit consumer contract.- Phase-4 storage uses dedicated runtime peers rather than broad device
authority.
drv-virtio-blockreceives a transferredDEVICE_FRAMEplus explicitmemd,vspaced, anddevicedpeers, whileblockdreceives separateREGISTER_HALandRESOLVE_PROVIDERsurfaces. - The BAR-derivation path uses a scratch local
DEVICE_FRAMEslot insidedeviced: the service validates the derived frame before startup-cap installation and drops that scratch slot on both success and failure paths so residual MMIO authority is not left behind locally. drv-virtio-blockbecomes activation-ready once its process and declared startup peers are live soblockdcan resolve it without a boot-time registration cycle; the later explicitREGISTER_PROVIDERcall still publishes the live endpoint and diagnostics.- Driver-start and provider-triggered ready logs stay queued until the outer
service loop reaches its normal flush point, so synchronous log mirroring does
not block concurrent control RPCs from
rootd. - Packaged release runtime builds select
deviced-runtime-release-image, which suppressesERIX_DEVICED:READY:*console stamps while still treating those internal lifecycle notifications as completed. - The runtime service loop now prioritizes housekeeping specifically for
pending-work
READ_DRIVERpolling, but transfer-backedREAD_DRIVERreplies restart the receive loop immediately instead of issuing an explicit scheduler yield. That keeps rootd's follow-on control RPCs ahead of unrelated freshly started drivers while still skipping post-reply housekeeping on the transfer path.REPORT_DEVICE/REPORT_HOTPLUGstill keep a reply-first path, but they no longer force an extra scheduler yield before bounded housekeeping runs, and rootd's admin verification bursts (READ_DEVICE,START_DRIVER->READ_DRIVER,STOP_DRIVER->READ_DRIVER) now stay on the admin endpoint fast path as well. PendingERIX_DEVICED:READY:*markers are flushed on that admin follow-on path before the loop resumes the next control RPC, and an idle miss still falls through one housekeeping pass before yielding. That avoids stranding already-woken control-plane callers such asrootdbehind unrelated discovery-side scheduling. Discovery replies still only admit a one-driver post-reply activation turn, while later control-driven housekeeping can activate a slightly larger bounded batch so serial and platform bring-up do not wait for a long tail of control polls. Because the split public endpoint family is multiplexed from one thread, the loop now keeps that receive scan non-blocking and yields explicitly when idle instead of registering a blocking receive on one endpoint that could strand admin traffic on another. PublicREGISTER_PROVIDERandREGISTER_HALreplies now also drain a short bounded admin burst before handing control back to the registering client, so phase3 serial and input bring-up cannot lose a just-wokenrootdREAD_DEVICE/lifecycle follow-on behind concurrent driver self-registration.READ_DRIVERnow also reconciles pending startup work before forming its reply, and it only re-delegates a runtime endpoint once provider visibility is actually established for roles likedrv-serial, so rootd can observe the newly-live provider without an extra poll round trip. - Start is denied for unknown/unsealed/running bindings.
- Stop is denied for unknown/non-running bindings.
- Responses are deterministic and panic-free.
- Driver start/stop goes through
procdin the current slice:- start uses
CREATE_STAGED_PROCESS+ install-grant materialization +START_STAGED_PROCESS - stop uses
STOP_PROCESS
- start uses
devicednow reachesprocdfor driver lifecycle through the dedicated local endpoint slotSLOT_PROCD_DRIVER_ENDPOINT (2112), validated via local capability introspection, instead of resolving the genericprocdservice endpoint throughnamed.deviced's primary local control slot is now the dedicated kernel log/query endpointSLOT_KERNEL_LOG_ENDPOINT (2272), which is limited toQUERY_CAP,LOG_STRING, andWRITE_LEGACY_SERIAL.devicednow stagesprobedfrom the explicit kernel PCI-config endpoint and stagesdrv-acpi,drv-serial, anddrv-i8042from dedicated localAcpiRead,Com1Io, andI8042Iosource endpoints.- Shared platform/device-I/O startup source slots are no longer part of the runtime driver contract.
devicednow also receives a grant-bearing localirqdpeer endpoint sodrv-serialcan receive its IRQ service endpoint through the staged child install-grant path rather than by shared-slot convention.- Driver startup peers are validated from delegated fixed slots, not from
ambient slot occupancy or synthetic
namedidentity.drv-serialand the PS/2 stack stay on exact declared startup-peer transfers. devicedno longer advertises or receives delegated CNode/TCB/VSpace management caps in the current runtime slice; driver lifecycle authority is reduced to the dedicatedprocddriver endpoint plus device-side authority.- Seeded driver metadata no longer includes a scalar device-cap source slot.
Driver hardware authority is expressed only through explicit transferred
startup caps;
deviceddoes not rely on unrelated boot metadata as a placeholder device cap. - Driver spawn requests now carry
procd's explicit local image-frame slot instead of reusing the canonical boot-module-table slot value. - Startup ready-state now uses caller-local
QUERY_LOCAL_CAPon bare metal, withQUERY_CAPretained for host/test scaffolding, to validate the actual local control slot, service endpoint slot, and every declared transferred slot. - The dedicated local driver-lifecycle and primary-control slots are now real
copied endpoint aliases materialized by
rootd, not implicit conventions. - Legacy synthetic direct-process-management fallbacks have been removed from
deviced; unsupported driver roles are denied at seed/start/stop time. - Startup-failure cleanup for supported service-managed drivers now also goes
back through
procdSTOP_PROCESS, not a direct kernel destroy path. - The helper driver binaries used by integration/validation also fail closed if bootstrap omits the startup endpoint argument; they no longer bind to conventional driver-window slots.
Build
cargo build --all-targets --all-features
Test
cargo test --all-targets --all-features
cargo clippy --all-targets --all-features -- -D warnings
Build and Test Modes
This repository supports additive runtime and integration feature gates.
*-runtimeand*-runtime-phase*features select production bootstrap/runtime behavior.*-integration-smokeremains available for synthetic end-to-end validation paths.*-integration-force-failremains test-only and MUST NOT be enabled for runtime appliance builds.- explicit driver primary-control omission/misroute features remain integration-only; they exist solely to prove fail-closed startup when staged driver authority is the wrong shape
Compatibility aliases are kept so existing scenario feature names continue to compile while the runtime naming becomes canonical.
The smoke-only READ_DEVICE reply markers remain cfg-scoped to
deviced-integration-smoke, so runtime/release appliance builds keep the
provider-registration reply path warning-free. The reply-path request-op decode
is now shared by runtime and smoke builds so the provider-registration fast path
compiles identically in appliance and integration configurations.
Governance Principles
deviced governance is scoped to device discovery, driver matching, and
provider publication.
The scoped governance rules are:
- It owns device-to-driver matching policy while drivers own hardware-specific behavior.
- It must start driver services only through
procdand transfer only the matched device authority. - It keeps provider registration explicit so consumers cannot discover devices through ambient authority.
- It rejects malformed manifests, duplicate providers, and unauthorized driver starts.
Authority Boundaries
devicedoperates only through startup-assigned service capabilities.- New authority must be represented in bootstrap/capability validation and integration tests before use.
Contact
Development occurs in EriX organization and discussions happen in issues and design documents.
No decisions are considered valid without documented rationale.
Maintainers can be reached via email: admin@erikinkinen.fi.