- Implement krealloc in linux-kpi memory.rs with GFP-aware tracker lookup,
copying, and zeroing of grown regions; add krealloc declaration to slab.h
- Align __GFP_ZERO/__GFP_NOWARN and GFP_* values between linux-kpi/slab.h
and redox_glue.h; make __GFP_ZERO a meaningful flag bit
- Add missing POSIX/errno base constants (EFBIG, EISDIR, ESPIPE, etc.) to
linux-kpi linux/errno.h so firmware-size checks and other drivers compile
- Harden linux-kpi bug.h: BUG()/BUG_ON() abort, WARN_ON_ONCE only warns once,
BUILD_BUG_ON uses _Static_assert
- Harden redox_glue.h: add PCI_COMMAND_* flags, CONFIG_HZ/HZ, jiffies
conversion macros, once-only WARN_ON_ONCE, _Static_assert BUILD_BUG_ON
- Implement redox_pci_enable_device/redox_pci_set_master with real local state
and command-bit updates; document pcid-spawner pre-enable
- Remove realloc-only krealloc from redox_stubs.c; it now links from linux-kpi
- Fix wait_for_completion_timeout to interpret timeout as jiffies and convert
to milliseconds, and update msecs/usecs_to_jiffies to use HZ
- Stage previously completed firmware-loader path deps and constructor fix
- Stage base and relibc submodule pointer updates from prior work
Replace version-string deps on redox_syscall, redox-scheme, and
libredox with path dependencies pointing to local/sources/ forks.
This aligns with local/AGENTS.md local-fork-dependency rule and
eliminates the crates.io vs local fork ambiguity that causes
mismatched-type link errors.
Replace ad-hoc struct literals scattered across the source with
named constructor methods (CacheMetadata::placeholder, CacheMetadata::from_source,
FirmwareFallback::load_defaults, FirmwareFallback::load_from_dir,
FirmwareFallback::builtins). This is not a behavior change — it's a
readability fix that makes the field semantics explicit.
Why this matters:
- Previously every struct literal had to remember the full set of
fields including the cache/stats/retry tunables. Adding a new field
required finding every literal in the source tree.
- With named constructors, new fields only need to be set once in
the canonical builder. Test/placeholder sites stay minimal.
- Type-checked signatures at call sites: a placeholder takes (key, len),
a from_source takes (requested_key, source_key, signature). The
compiler now verifies you pass a SourceSignature when you need one.
Cross-referenced with Linux drivers/base/firmware_loader.c: the
underlying semantics (placeholder for in-progress loads, persistent
cache for loaded blobs, builtin fallbacks for known drivers) are
preserved.
Previously: host_redox_stubs returned ENOSYS for all syscalls except
close/munmap/get_euid/ruid/egid/rgid — silent failures when IOMMU
code was tested on the host.
Now (host only):
- open/read/write/close → real libc file I/O
- mmap → real libc memory allocation (MAP_ANON|MAP_PRIVATE)
- munmap → real libc munmap
- clock_gettime → real libc CLOCK_REALTIME
- fstat → real libc fstat
- fsync/fdatasync/ftruncate → real libc ops
- getpid/getuid/geteuid/getgid/getegid → real libc
- strerror → real libc strerror (not hardcoded message)
- 12 remaining unsupported ops: ENOSYS with same semantics
(dup, signals, waitpid, namespaces — not needed for IOMMU tests)
Systemic fix: all local recipes (~150 references across 40+ Cargo.toml files)
now resolve libredox, redox_syscall, and redox-scheme through
recipes/core/base/ symlinks instead of local/sources/ paths.
Eliminates lockfile collision between Cargo's resolution of the same
package through different path strings (local/sources/ vs recipes/core/base/).
This is required because the base recipe's workspace Cargo.toml resolves
these deps through recipes/core/base/ (via symlink chain from the
recipe copy location), and Cargo treats different path strings to the
same directory as different packages.
The previous tokio = { features = ["full"] } pulled in tokio::signal
(including tokio::signal::unix::SignalKind::terminate). On Redox the
libc signal-handler registration path is incomplete; calling
enable_all() in main triggered a protection fault inside relibc, and
the kernel then panicked on unreachable code in
process::exit_this_context (see kernel/src/syscall/process.rs:79).
Two-part fix:
- Cargo.toml: scope tokio features to rt, rt-multi-thread, macros,
net, time, sync. This drops and , which are
unavailable on Redox anyway. The init system manages the daemon
lifecycle, so a signal handler is not needed in this daemon.
- src/main.rs: spawn_signal_handler becomes a no-op. The shutdown_tx
channel is preserved for any future internal shutdown signaling.
The SIGTERM path is removed entirely.
This unblocks Phase 2.1 by removing the kernel panic cascade: the
protection fault no longer fires, the kernel's exit_this_context
reaches the context switch cleanly, and the previous
unreachable!() panic no longer triggers.
Cross-compile error: from_bits_truncate requires u8 but
O_STAT/O_RDWR are usize. Cast with 'as u8'.
Applied to all 4 scheme wrappers: acmd, ftdi, ecmd, usbaudiod.
redbear-ecmd: scheme loop replaces stdout on Redox
(/scheme/net/usbECM_<N>), notification reader kept for
CDC link state / speed change events on both paths.
redbear-usbaudiod: scheme loop replaces stdout on Redox
(/scheme/audio/usbAudio_<N>), stdin→isoch_OUT playback
thread kept for host stdout path only.
All 4 class drivers now fully wired:
acmd → scheme event loop active on Redox ✅
ftdi → scheme event loop active on Redox ✅
ecmd → scheme event loop active on Redox ✅
usbaudiod → scheme event loop active on Redox ✅
redbear-ecmd: EcmScheme → /scheme/net/usbECM_<N> for netstack
redbear-usbaudiod: AudioScheme → /scheme/audio/usbAudio_<N> for audiod
(supports capture/playback path routing via openat path names)
All 4 class drivers now have scheme service wrappers:
redbear-acmd → /scheme/ttys/usbACM_<N>
redbear-ftdi → /scheme/ttys/usbFTDI_<N>
redbear-ecmd → /scheme/net/usbECM_<N>
redbear-usbaudiod → /scheme/audio/usbAudio_<N>
(HID+Storage already have scheme integration via ProducerHandle/DiskScheme)
Cross-referenced with Linux 7.1 tty_port_register_device() pattern.
New scheme.rs module:
- AcmScheme implements SchemeSync with Mutex-wrapped XhciEndpHandle
- openat(): root dir listing + device file open (O_RDWR)
- read(): USB bulk IN → scheme client (getty, terminal)
- write(): scheme client → USB bulk OUT
- close(): decrements open count
- fsync(): no-op
main.rs:
- #[cfg(target_os = redox)]: Socket::create() + register scheme
under /scheme/ttys/usbACM_<port_id>, process requests with
handle_scheme_mut() in event loop
- #[cfg(not(target_os = redox))]: stdout fallback for testing
This enables getty to open /scheme/ttys/usbACM_<N> as a serial
console on USB CDC ACM devices — the driver is now a proper
Redox scheme service, not just a stdout debugging tool.
Pattern replicable for redbear-ftdi (same scheme:ttys), redbear-ecmd
(scheme:net), and redbear-usbaudiod (scheme:audio).
The Redox init system connects daemon stdout to the appropriate
scheme service on spawn. No explicit scheme registration needed
in the driver — stdout/stderr are the scheme IPC endpoints.
This is the standard Redox daemon architecture:
- Input daemons (HID, storage) write to stdout → scheme:input, scheme:disk
- Output daemons (ACM, ECM, Audio) read/write stdout → scheme:ttys, scheme:net
- The init system handles pipe-to-scheme binding via .service files
Removed unused redox-scheme dependency that was added for a
Socket::accept()-based approach (accept() not available in this
version of redox-scheme). The stdout pattern is the correct,
working architecture.
usb-core spawn.rs:
- class_driver_for_usb_class() extended to cover all Red Bear class drivers:
Audio(0x01)→redbear-usbaudiod, CDC ACM(0x02/0x02)→redbear-acmd,
CDC ECM(0x02/0x06)→redbear-ecmd, HID(0x03)→usbhidd,
Mass Storage(0x08)→usbscsid, Hub(0x09)→usbhubd,
Vendor(0xFF)→redbear-ftdi
- Subclass-aware matching (Audio Control vs Streaming, CDC ACM vs ECM)
- is_trusted_usb_driver() whitelist extended with all 7 driver binaries
- Test suite updated with new assertions (11/11 pass)
redbear-usb-hotplugd:
- DRIVER_MAP extended to 11 entries with subclass-aware matching
- Recursive port scanning: scan_ports_recursive() traverses child
hub port directories (handles port1.port2.port3 paths)
- extract_port_id() parses full port paths to extract controller
name and port string for child hub ports
- Protocol-aware extra arg: Storage passes protocol byte (0x50/0x62),
all other classes pass interface number
- Skips CDC Data interfaces (0x0A) and hub interfaces (0x09) when
reading descriptors — matches Linux's interface matching logic
- Improved disconnect detection via descriptor accessibility heuristic
- Cleaner structure: find_driver(), scan_controllers(), scan_ports(),
try_read_descriptors(), main loop with connect/disconnect tracking
All 7 Red Bear USB class drivers now auto-spawning on device connect:
usbhidd, usbscsid, usbhubd, redbear-acmd, redbear-ecmd,
redbear-usbaudiod, redbear-ftdi
Add a JsonLoad struct with load_avg_1m/5m/15m fields and include it in the --json snapshot. Values are read from app.load_avg. Build, 224 tests, clippy, and fmt clean.
Cross-referenced with Linux 7.1 drivers/usb/core/hub.c port event
handling and drivers/usb/core/driver.c device-driver binding.
New daemon (216 lines) that watches USB controllers for device
attachment/detachment and auto-spawns the appropriate class driver.
Architecture:
- Polls /scheme/usb/ every 1000ms for controller directories
- For each controller, enumerates root hub ports
- Reads device descriptors (class/subclass/protocol) via XhciClientHandle
- Maps class to driver binary: HID(0x03)→usbhidd, Storage(0x08)→usbscsid,
Hub(0x09)→usbhubd
- Spawns driver with <scheme> <port> <protocol> arguments
- Tracks spawned Child processes in HashMap<port_path, TrackedDevice>
- Detects disconnection (descriptor read fails) → kills driver + removes
from tracking
- Detects driver exit (try_wait) → removes from tracking
- Skips hub interfaces (usbhubd handles its own children)
Config:
- Added to redbear-mini.toml (inherited by redbear-full)
- Auto-started via 02_usb_hotplug.service (oneshot_async, after base.target
and pcid-spawner)
Driver map supports: HID (0x03), Mass Storage (0x08 with BOT protocol),
Hub (0x09). Additional class drivers extendable via DRIVER_MAP constant.
Mirror the local process_filter_input buffer into App so render_keybar can display it. While filtering, the keybar shows "Filter: <buffer> (N matches) Enter:apply Esc:clear ↑↓:select" in a warm style instead of the normal hints. Build, 224 tests, clippy, and fmt clean.
Replace the generic kill-dialog footer with an explicit confirmation line: "Send SIGTERM to PID 1234 (sshd)? Enter: send Esc: cancel ↑↓: select". Extracts the signal name from the existing signal labels. Build, 224 tests, clippy, and fmt clean.
Add refresh_ms to SessionState (0 = not set, use config/default). Load it into App::poll_ms, give it priority over config when initializing the event-loop poll interval, and save it back in save_session(). Update all SessionState test initializers and assertions. Build, 224 tests, clippy, and fmt clean.
Extend the header load-average line to also show system uptime and total process count. Uptime uses meminfo::format_uptime; process count uses app.processes.count(). All values stay on one line to keep HEADER_LINES at 8. Build, 224 tests, clippy, and fmt clean.
Cross-referenced with Linux 7.1 sound/usb/card.c, mixer.c, pcm.c
and include/uapi/linux/usb/audio.h.
Replaces the 32-line scan-and-symlink stub with a 280-line real class driver:
Audio Control Interface (Feature Unit):
- Volume control: GET_CUR / SET_CUR via class-specific control requests
(bmRequestType 0xA1/0x21, FU_VOLUME selector, per-channel)
- Mute control: GET_CUR / SET_CUR (FU_MUTE selector)
- AudioReq helper for bidirectional class-specific control requests
Audio Streaming Interface:
- Isochronous endpoint auto-detection (attributes & 0x03 == 0x01)
- Format heuristics from max packet size (stereo 16-bit 48kHz default)
- SET_CUR SAMPLING_FREQ_CONTROL (0x0100) for sample rate
- Bidirectional isoch I/O: isoch IN → stdout (recording),
stdin → isoch OUT (playback)
Eliminates P1-D last remaining stub — all 3 scan-and-symlink stubs
(ecmd, acmd, usbaudiod) now have real class driver implementations.
Add a "Load: 0.42 0.55 0.61" line to render_header, color-coded by load versus core count (green <= 50% capacity, yellow <= 100%, red overcommitted). Bump HEADER_LINES from 7 to 8. Build, 224 tests, clippy, and fmt clean.