Update USB boot docs and relibc patch overlays
This commit is contained in:
@@ -141,6 +141,48 @@ Acceptance:
|
|||||||
- keep laptop input as a boot-resilience feature, not a desktop-only feature
|
- keep laptop input as a boot-resilience feature, not a desktop-only feature
|
||||||
- treat Intel and AMD laptops as equal-priority hardware targets
|
- treat Intel and AMD laptops as equal-priority hardware targets
|
||||||
|
|
||||||
|
## Other Boot-Relevant I2C Device Classes
|
||||||
|
|
||||||
|
`I2C-HID` is the first and most important I2C deliverable, but it is not the only I2C-related
|
||||||
|
surface that can matter during boot on modern bare metal.
|
||||||
|
|
||||||
|
### Highest priority after `I2C-HID`
|
||||||
|
|
||||||
|
- GPIO expanders used to expose reset, enable, interrupt, or wake lines for input devices
|
||||||
|
- platform-specific I2C controller companions that gate access to the actual `I2C-HID` device
|
||||||
|
|
||||||
|
These are not always directly user-visible as "devices", but they are boot-relevant whenever the
|
||||||
|
keyboard/touchpad path depends on them.
|
||||||
|
|
||||||
|
### Sometimes boot-relevant
|
||||||
|
|
||||||
|
- USB-C / UCSI / PD related I2C-attached endpoints on platforms where a USB-C attached keyboard or
|
||||||
|
dock path is firmware-mediated and not available without those services
|
||||||
|
- embedded controller-adjacent I2C peripherals that gate keyboard/touchpad power or wake routing
|
||||||
|
|
||||||
|
These should be treated as platform-dependent bring-up work, not as universal phase-1 targets.
|
||||||
|
|
||||||
|
### Not first-order blockers for reaching login
|
||||||
|
|
||||||
|
- sensors (accelerometer, gyro, ambient light)
|
||||||
|
- battery / charger / fuel-gauge devices
|
||||||
|
- camera-side I2C devices
|
||||||
|
- most audio codecs and amplifier control devices
|
||||||
|
- thermal and fan-adjacent I2C sensors
|
||||||
|
|
||||||
|
These matter for full laptop support, but they do not outrank keyboard/touchpad bring-up for live
|
||||||
|
boot and recovery.
|
||||||
|
|
||||||
|
## Boot Priority Order
|
||||||
|
|
||||||
|
For boot-to-login on modern laptops, the correct priority is:
|
||||||
|
|
||||||
|
1. `I2C-HID` keyboards and touchpads
|
||||||
|
2. any GPIO-expander or companion I2C devices required to make those devices usable
|
||||||
|
3. platform-specific USB-C / UCSI I2C surfaces only on machines that actually depend on them for
|
||||||
|
input availability
|
||||||
|
4. all other I2C-attached peripherals
|
||||||
|
|
||||||
## Immediate Next Steps
|
## Immediate Next Steps
|
||||||
|
|
||||||
1. land `_CRS` decoding in `acpid`
|
1. land `_CRS` decoding in `acpid`
|
||||||
|
|||||||
@@ -0,0 +1,169 @@
|
|||||||
|
# USB Boot Input Plan
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
Make external USB keyboards a reliable bare-metal boot fallback for Red Bear OS.
|
||||||
|
|
||||||
|
This is a boot-resilience requirement, not optional polish. A system that reaches early
|
||||||
|
boot but cannot accept keyboard input on modern hardware is not a complete live/recovery
|
||||||
|
environment.
|
||||||
|
|
||||||
|
## Current Assessment
|
||||||
|
|
||||||
|
### What works today
|
||||||
|
|
||||||
|
- `xhcid` is the only host-controller path with a real runtime device model.
|
||||||
|
- `xhcid` spawns `usbhubd` and `usbhidd` via class matching.
|
||||||
|
- `usbhidd` reads HID input reports and forwards keyboard/mouse events into `inputd`.
|
||||||
|
|
||||||
|
This means USB keyboard input can work today only when the keyboard is reached through the
|
||||||
|
`xHCI -> usbhubd/usbhidd -> inputd` path.
|
||||||
|
|
||||||
|
### What does not work today
|
||||||
|
|
||||||
|
- `ehcid` is still an ownership / handoff / port-state daemon, not a real runtime host stack.
|
||||||
|
- `uhcid` is still ownership + port reset + logging only; full scheduling/enumeration is explicitly
|
||||||
|
not implemented.
|
||||||
|
- `ohcid` is in the same state as `uhcid`.
|
||||||
|
|
||||||
|
The code is explicit about this:
|
||||||
|
|
||||||
|
- `ehcid`: connected EHCI-owned ports still fail with "EHCI enumeration is still not implemented"
|
||||||
|
- `uhcid`: connected ports still fail with "runtime enumeration is still not implemented"
|
||||||
|
- `ohcid`: connected ports still fail with "OHCI enumeration is still not implemented"
|
||||||
|
|
||||||
|
### Important practical consequence
|
||||||
|
|
||||||
|
An external USB keyboard on bare metal is **not guaranteed** to appear through `xHCI`.
|
||||||
|
|
||||||
|
It may instead land on:
|
||||||
|
|
||||||
|
- an EHCI root-hub path
|
||||||
|
- a UHCI/OHCI companion path after EHCI handoff
|
||||||
|
- a firmware/routing topology where low/full-speed devices do not end up on the `xHCI` runtime path
|
||||||
|
|
||||||
|
On such systems, the current code can detect controller ownership and connected ports, but still
|
||||||
|
cannot produce a real keyboard input path.
|
||||||
|
|
||||||
|
### LED state is a separate and weaker path
|
||||||
|
|
||||||
|
`usbhidd` now has a bounded best-effort HID output-report path for keyboard LEDs. It toggles
|
||||||
|
`Caps Lock`, `Num Lock`, and `Scroll Lock` locally on keydown and sends a one-byte HID output
|
||||||
|
report via `SET_REPORT`.
|
||||||
|
|
||||||
|
This is useful, but it is **not** the same as a complete global keyboard lock-state authority:
|
||||||
|
|
||||||
|
- it is per-device, not system-global
|
||||||
|
- it is best-effort and disables itself after the first device-side failure
|
||||||
|
- it does not solve missing USB enumeration on non-xHCI host-controller paths
|
||||||
|
|
||||||
|
So dead `Caps Lock` / `Num Lock` indicators still do **not** prove that keyboard transport is dead,
|
||||||
|
and working LEDs do **not** prove that the external USB keyboard fallback problem is solved.
|
||||||
|
|
||||||
|
## Root-Cause Summary For Current Bare-Metal Symptom
|
||||||
|
|
||||||
|
When a USB-attached keyboard does not bring up input during boot, the most likely causes are:
|
||||||
|
|
||||||
|
1. the keyboard is not on the `xHCI` runtime path
|
||||||
|
2. it lands on `EHCI/UHCI/OHCI`, where enumeration is not implemented yet
|
||||||
|
3. even if input later works, keyboard LEDs may still be misleading because LED sync is only a
|
||||||
|
bounded per-device best-effort path
|
||||||
|
|
||||||
|
## Current Structural Gap
|
||||||
|
|
||||||
|
There is also a policy gap:
|
||||||
|
|
||||||
|
- `ehcid`, `uhcid`, and `ohcid` contain `--strict-boot` logic
|
||||||
|
- and the current boot path still does **not** hardcode `--strict-boot` in initfs driver command lines
|
||||||
|
- however, strict mode can now be enabled through `REDBEAR_STRICT_USB_BOOT=1`, which is inherited by
|
||||||
|
`pcid-spawner` service units and then by legacy USB controller daemons
|
||||||
|
|
||||||
|
So the code contains a boot-guard concept that is currently not activated by the initfs spawn path.
|
||||||
|
|
||||||
|
This does not create input support by itself, but it does matter for observability and boot policy.
|
||||||
|
|
||||||
|
## Execution Order
|
||||||
|
|
||||||
|
### Phase U-B1: Make boot policy honest
|
||||||
|
|
||||||
|
Deliverables:
|
||||||
|
|
||||||
|
- decide whether initfs should pass `--strict-boot` to legacy USB host daemons
|
||||||
|
- provide a non-invasive runtime toggle for strict mode during bring-up
|
||||||
|
- if enabled, make the failure mode explicit and bounded
|
||||||
|
- if not enabled, log clearly that legacy USB ownership exists without runtime enumeration
|
||||||
|
|
||||||
|
Acceptance:
|
||||||
|
|
||||||
|
- the boot log makes it obvious whether the system has a usable USB keyboard path or only controller
|
||||||
|
ownership
|
||||||
|
- strict mode can be enabled without rewriting driver command lines
|
||||||
|
|
||||||
|
### Phase U-B2: Finish legacy host runtime enumeration
|
||||||
|
|
||||||
|
Deliverables:
|
||||||
|
|
||||||
|
- implement real device enumeration for `uhcid`
|
||||||
|
- implement real device enumeration for `ohcid`
|
||||||
|
- implement real runtime ownership of low/full-speed devices behind `ehcid` companion routing
|
||||||
|
|
||||||
|
Acceptance:
|
||||||
|
|
||||||
|
- a low/full-speed USB keyboard on bare metal can reach `usbhidd` through the legacy host path
|
||||||
|
|
||||||
|
### Phase U-B3: Keep one HID class path
|
||||||
|
|
||||||
|
Deliverables:
|
||||||
|
|
||||||
|
- avoid inventing a second HID stack just for legacy controllers
|
||||||
|
- make legacy host controllers feed the existing USB class-driver model
|
||||||
|
- keep `usbhidd` and `usbhubd` as the class daemons above controller-specific ownership
|
||||||
|
|
||||||
|
Acceptance:
|
||||||
|
|
||||||
|
- keyboard class handling is shared regardless of host controller family
|
||||||
|
|
||||||
|
### Phase U-B4: Implement keyboard LED output
|
||||||
|
|
||||||
|
Deliverables:
|
||||||
|
|
||||||
|
- keep the new HID output-report support in `usbhidd` bounded and non-fatal
|
||||||
|
- decide whether the current per-device local toggle model is sufficient, or whether Red Bear
|
||||||
|
later needs a system-authoritative lock-state surface
|
||||||
|
- preserve the rule that LED sync must never block or destabilize keyboard input
|
||||||
|
|
||||||
|
Acceptance:
|
||||||
|
|
||||||
|
- LED state tracks keyboard lock state on at least one supported USB keyboard in the current
|
||||||
|
bounded per-device model
|
||||||
|
|
||||||
|
### Phase U-B5: Validation
|
||||||
|
|
||||||
|
Deliverables:
|
||||||
|
|
||||||
|
- QEMU validation for xHCI remains
|
||||||
|
- add bounded validation for legacy host-controller paths where feasible
|
||||||
|
- require bare-metal validation on systems where external USB keyboard currently fails
|
||||||
|
|
||||||
|
Acceptance:
|
||||||
|
|
||||||
|
- one xHCI bare-metal proof
|
||||||
|
- one EHCI/UHCI/OHCI-involved bare-metal proof
|
||||||
|
- explicit evidence that external USB keyboard input reaches login
|
||||||
|
|
||||||
|
## Design Rules
|
||||||
|
|
||||||
|
- do not treat controller ownership as equivalent to device enumeration
|
||||||
|
- do not treat keyboard LED state as equivalent to keyboard input health
|
||||||
|
- reuse the existing HID class-driver path instead of splitting per-controller userland stacks
|
||||||
|
- prefer bounded boot-policy checks and explicit failure logs over silent partial bring-up
|
||||||
|
|
||||||
|
## Priority Judgment
|
||||||
|
|
||||||
|
For bare-metal boot resilience, the correct order is:
|
||||||
|
|
||||||
|
1. finish legacy USB host runtime enumeration
|
||||||
|
2. then add keyboard LED output reports
|
||||||
|
3. in parallel, continue `I2C-HID` for internal modern laptop keyboards/touchpads
|
||||||
|
|
||||||
|
External USB keyboard fallback and internal `I2C-HID` are complementary. Red Bear needs both.
|
||||||
@@ -53,6 +53,26 @@ The Red Bear USB stack consists of:
|
|||||||
full stack, and storage autospawn
|
full stack, and storage autospawn
|
||||||
- an in-guest scheme-tree checker (`redbear-usb-check`)
|
- an in-guest scheme-tree checker (`redbear-usb-check`)
|
||||||
|
|
||||||
|
### Boot-input reality
|
||||||
|
|
||||||
|
For bare-metal boot resilience, the current USB stack is still incomplete.
|
||||||
|
|
||||||
|
External USB keyboard input is reliably available only when the keyboard is reached through the
|
||||||
|
`xHCI -> usbhubd/usbhidd -> inputd` path. This is an important distinction because modern bare
|
||||||
|
metal does not guarantee that an attached keyboard will land on the xHCI runtime path.
|
||||||
|
|
||||||
|
If a keyboard instead lands on:
|
||||||
|
|
||||||
|
- an EHCI-owned path
|
||||||
|
- a UHCI/OHCI companion path
|
||||||
|
- a firmware routing topology where low/full-speed devices do not reach the xHCI runtime path
|
||||||
|
|
||||||
|
then Red Bear may still detect controller ownership and connected ports, but it does not yet have a
|
||||||
|
complete runtime host path that reaches the existing HID class daemons.
|
||||||
|
|
||||||
|
This means Red Bear cannot yet honestly claim that an external USB keyboard is a reliable universal
|
||||||
|
boot fallback on bare metal.
|
||||||
|
|
||||||
### Red Bear xHCI Patch Layer
|
### Red Bear xHCI Patch Layer
|
||||||
|
|
||||||
The Red Bear patch at `local/patches/base/redox.patch` carries these changes over the upstream
|
The Red Bear patch at `local/patches/base/redox.patch` carries these changes over the upstream
|
||||||
@@ -105,12 +125,17 @@ source:
|
|||||||
Even with the Red Bear patch applied:
|
Even with the Red Bear patch applied:
|
||||||
|
|
||||||
- HID is still wired through the legacy mixed-stream `inputd` path
|
- HID is still wired through the legacy mixed-stream `inputd` path
|
||||||
|
- external USB keyboard fallback is not guaranteed on bare metal unless the keyboard reaches the
|
||||||
|
xHCI runtime path
|
||||||
|
- EHCI/UHCI/OHCI are not yet full runtime host-controller implementations
|
||||||
- Any remaining USB composite/device-model issues now sit above the bounded helper fixes already
|
- Any remaining USB composite/device-model issues now sit above the bounded helper fixes already
|
||||||
landed for active alternates, endpoint direction, real interface/alternate hub configuration, and
|
landed for active alternates, endpoint direction, real interface/alternate hub configuration, and
|
||||||
SSP-aware endpoint-context calculations.
|
SSP-aware endpoint-context calculations.
|
||||||
- ~57 TODO/FIXME comments remain across xHCI driver files
|
- ~57 TODO/FIXME comments remain across xHCI driver files
|
||||||
- usbhubd: interrupt-driven change detection implemented; 1-second polling retained as fallback
|
- usbhubd: interrupt-driven change detection implemented; 1-second polling retained as fallback
|
||||||
- usbscsid: `ReadCapacity16` now implemented with automatic fallback from `ReadCapacity10`
|
- usbscsid: `ReadCapacity16` now implemented with automatic fallback from `ReadCapacity10`
|
||||||
|
- `usbhidd` keyboard LED sync is only a bounded per-device best-effort path, not a system-global
|
||||||
|
lock-state authority
|
||||||
- No real hardware USB validation — all testing is QEMU-only
|
- No real hardware USB validation — all testing is QEMU-only
|
||||||
- No hot-plug stress testing
|
- No hot-plug stress testing
|
||||||
- No USB storage data I/O validation (autospawn checked, but no read/write tested)
|
- No USB storage data I/O validation (autospawn checked, but no read/write tested)
|
||||||
@@ -124,8 +149,9 @@ Even with the Red Bear patch applied:
|
|||||||
|---|---|---|
|
|---|---|---|
|
||||||
| Host mode | **builds / QEMU-validated** | Real host-side stack, interrupt-driven, QEMU-validated only |
|
| Host mode | **builds / QEMU-validated** | Real host-side stack, interrupt-driven, QEMU-validated only |
|
||||||
| xHCI controller | **builds / QEMU-validated** | Red Bear patch: 88 error handling fixes, ERDP split, endp_direction fix, cfg_idx fix, real grow_event_ring, mutex poison recovery on all hot-path locks; no real hardware validation yet |
|
| xHCI controller | **builds / QEMU-validated** | Red Bear patch: 88 error handling fixes, ERDP split, endp_direction fix, cfg_idx fix, real grow_event_ring, mutex poison recovery on all hot-path locks; no real hardware validation yet |
|
||||||
|
| EHCI/UHCI/OHCI | **builds / enumerates** | Ownership, port handling, and logging exist, but they are not yet full runtime enumeration paths |
|
||||||
| Hub handling | **builds / good quality** | `usbhubd`: all `expect()` eliminated, interrupt-driven change detection with polling fallback, graceful per-port error handling |
|
| Hub handling | **builds / good quality** | `usbhubd`: all `expect()` eliminated, interrupt-driven change detection with polling fallback, graceful per-port error handling |
|
||||||
| HID | **builds / QEMU-validated in narrow path** | `usbhidd` handles keyboard/mouse/button/scroll via legacy input path, no panics in report loop |
|
| HID | **builds / QEMU-validated in narrow path** | `usbhidd` handles keyboard/mouse/button/scroll via legacy input path, no panics in report loop; keyboard LED sync exists as a bounded per-device best-effort path |
|
||||||
| Mass storage | **builds / good quality** | `usbscsid`: typed `ScsiError`, fallible parsing, `ReadCapacity16` for >2TB, stall recovery, resilient event loop |
|
| Mass storage | **builds / good quality** | `usbscsid`: typed `ScsiError`, fallible parsing, `ReadCapacity16` for >2TB, stall recovery, resilient event loop |
|
||||||
| Native tooling | **builds / enumerates** | `lsusb`, `usbctl`, `redbear-info`, `redbear-usb-check` provide observability |
|
| Native tooling | **builds / enumerates** | `lsusb`, `usbctl`, `redbear-info`, `redbear-usb-check` provide observability |
|
||||||
| Low-level userspace API | **builds** | `xhcid_interface` with `UsbSpeed` enum, `attach_with_speed()` |
|
| Low-level userspace API | **builds** | `xhcid_interface` with `UsbSpeed` enum, `attach_with_speed()` |
|
||||||
|
|||||||
@@ -1,18 +1,10 @@
|
|||||||
diff --git a/src/header/fcntl/mod.rs b/src/header/fcntl/mod.rs
|
diff --git a/src/header/fcntl/mod.rs b/src/header/fcntl/mod.rs
|
||||||
--- a/src/header/fcntl/mod.rs
|
--- a/src/header/fcntl/mod.rs
|
||||||
+++ b/src/header/fcntl/mod.rs
|
+++ b/src/header/fcntl/mod.rs
|
||||||
@@ -8,6 +8,7 @@ use crate::{
|
@@ -9,0 +10 @@
|
||||||
c_str::CStr,
|
|
||||||
error::{Errno, ResultExt},
|
|
||||||
header::errno::ENAMETOOLONG,
|
|
||||||
+ header::unistd::close,
|
+ header::unistd::close,
|
||||||
platform::{
|
@@ -75,0 +77,17 @@
|
||||||
Pal, Sys,
|
+
|
||||||
types::{
|
|
||||||
@@ -78,6 +79,23 @@ pub unsafe extern "C" fn fcntl(fildes: c_int, cmd: c_int, mut __valist: ...) ->
|
|
||||||
_ => 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
+ if cmd == F_DUPFD_CLOEXEC {
|
+ if cmd == F_DUPFD_CLOEXEC {
|
||||||
+ let new_fd = Sys::fcntl(fildes, F_DUPFD_CLOEXEC, arg).or_minus_one_errno();
|
+ let new_fd = Sys::fcntl(fildes, F_DUPFD_CLOEXEC, arg).or_minus_one_errno();
|
||||||
+ if new_fd >= 0 {
|
+ if new_fd >= 0 {
|
||||||
@@ -29,6 +21,3 @@ diff --git a/src/header/fcntl/mod.rs b/src/header/fcntl/mod.rs
|
|||||||
+ }
|
+ }
|
||||||
+ return new_fd;
|
+ return new_fd;
|
||||||
+ }
|
+ }
|
||||||
+
|
|
||||||
Sys::fcntl(fildes, cmd, arg).or_minus_one_errno()
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,37 +1,10 @@
|
|||||||
diff --git a/src/c/stdlib.c b/src/c/stdlib.c
|
|
||||||
index 62e98108..a9c72392 100644
|
|
||||||
--- a/src/c/stdlib.c
|
|
||||||
+++ b/src/c/stdlib.c
|
|
||||||
@@ -4,6 +4,13 @@ long double strtold(const char *nptr, char **endptr) {
|
|
||||||
return (long double)strtod(nptr, endptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
+long double relibc_compat_cpp_strtold(const char *nptr, char **endptr)
|
|
||||||
+ __asm__("_Z7strtoldPKcPPc");
|
|
||||||
+
|
|
||||||
+long double relibc_compat_cpp_strtold(const char *nptr, char **endptr) {
|
|
||||||
+ return strtold(nptr, endptr);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
double relibc_ldtod(const long double* val) {
|
|
||||||
return (double)(*val);
|
|
||||||
}
|
|
||||||
diff --git a/src/header/fcntl/mod.rs b/src/header/fcntl/mod.rs
|
diff --git a/src/header/fcntl/mod.rs b/src/header/fcntl/mod.rs
|
||||||
index ec37906c..95604e06 100644
|
|
||||||
--- a/src/header/fcntl/mod.rs
|
--- a/src/header/fcntl/mod.rs
|
||||||
+++ b/src/header/fcntl/mod.rs
|
+++ b/src/header/fcntl/mod.rs
|
||||||
@@ -8,6 +8,7 @@ use crate::{
|
@@ -9,0 +10 @@
|
||||||
c_str::CStr,
|
|
||||||
error::{Errno, ResultExt},
|
|
||||||
header::errno::ENAMETOOLONG,
|
|
||||||
+ header::unistd::close,
|
+ header::unistd::close,
|
||||||
platform::{
|
@@ -75,0 +77,17 @@
|
||||||
Pal, Sys,
|
+
|
||||||
types::{
|
|
||||||
@@ -78,6 +79,23 @@ pub unsafe extern "C" fn fcntl(fildes: c_int, cmd: c_int, mut __valist: ...) ->
|
|
||||||
_ => 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
+ if cmd == F_DUPFD_CLOEXEC {
|
+ if cmd == F_DUPFD_CLOEXEC {
|
||||||
+ let new_fd = Sys::fcntl(fildes, F_DUPFD_CLOEXEC, arg).or_minus_one_errno();
|
+ let new_fd = Sys::fcntl(fildes, F_DUPFD_CLOEXEC, arg).or_minus_one_errno();
|
||||||
+ if new_fd >= 0 {
|
+ if new_fd >= 0 {
|
||||||
@@ -48,6 +21,3 @@ index ec37906c..95604e06 100644
|
|||||||
+ }
|
+ }
|
||||||
+ return new_fd;
|
+ return new_fd;
|
||||||
+ }
|
+ }
|
||||||
+
|
|
||||||
Sys::fcntl(fildes, cmd, arg).or_minus_one_errno()
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user