Compare commits
47 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| cd3950072e | |||
| 1baa769241 | |||
| a998484765 | |||
| af21591a98 | |||
| 32a217f9e5 | |||
| a53946aecf | |||
| 27bb5e3f0e | |||
| b8fbb8bfc5 | |||
| 14913dc6f3 | |||
| 1d34a67dd3 | |||
| ff05c9f596 | |||
| 44e6665a4a | |||
| fb827fad85 | |||
| 3d2392eb2e | |||
| e524350cf3 | |||
| 32a776771c | |||
| 34a11d845b | |||
| 533a1c2969 | |||
| f495587972 | |||
| 8e98ae1270 | |||
| bb6d2ad95e | |||
| c52cec97cd | |||
| 768010de46 | |||
| c120c3519f | |||
| 3671ca573c | |||
| a3a4d4cde9 | |||
| 5cde25495c | |||
| 48dfbc5ffc | |||
| fcd8722f92 | |||
| 6dd30b80b4 | |||
| 5725acc7dc | |||
| 5897eefc3a | |||
| 9d5a6319f8 | |||
| 1834c3bf58 | |||
| adae16ace3 | |||
| 32403ccf4b | |||
| 339cd4e223 | |||
| bea67affad | |||
| 8b2ed82995 | |||
| 23ef3fdd3f | |||
| 1d3878ee78 | |||
| 68966c67eb | |||
| 73408a1609 | |||
| 760ec887f3 | |||
| 8501245598 | |||
| 4d270bab29 | |||
| 4191b8543e |
+16
-2
@@ -13,8 +13,12 @@
|
||||
# Nested recipe debris from prior build-system layouts (4.2GB+ of duplicates)
|
||||
recipes/recipes/
|
||||
|
||||
# Fetched source trees in mainline recipes (not our code in local/)
|
||||
# Matches recipes/<category>/<name>/source/ but NOT local/recipes/*/source/
|
||||
# Fetched source trees in mainline recipes AND in specific local/ build-cache
|
||||
# recipes (those whose source/ is a transient working copy re-fetched by the
|
||||
# build system from the recipe's `git` URL). The durable code for these is
|
||||
# recipe.toml + local/patches/. — DO NOT add a blanket `local/recipes/**/source`
|
||||
# rule here: ~150 Red Bear recipes have durable source code under
|
||||
# `local/recipes/<name>/source/` (the fork model).
|
||||
recipes/**/source
|
||||
recipes/**/source.tmp
|
||||
recipes/**/source-new
|
||||
@@ -22,6 +26,10 @@ recipes/**/source-old
|
||||
recipes/**/source.tar
|
||||
recipes/**/source.tar.tmp
|
||||
recipes/**/source.pre-preservation-test/
|
||||
local/recipes/archives/uutils-tar/source
|
||||
local/recipes/dev/ninja-build/source
|
||||
local/recipes/kde/sddm/source
|
||||
local/recipes/kde/sddm/source-pristine
|
||||
|
||||
# Build artifacts — target/ dirs are everywhere
|
||||
target
|
||||
@@ -31,6 +39,12 @@ wget-log
|
||||
# Vendor source trees (fetched, not our code)
|
||||
**/amdgpu-source/
|
||||
|
||||
# External reference trees (read-only consultation sources). The Linux
|
||||
# reference tree (local/reference/linux-7.1) is currently kept locally
|
||||
# but is gitignored by size; seL4 reference is an empty placeholder.
|
||||
local/reference/linux-*/
|
||||
local/reference/seL4/
|
||||
|
||||
# Compiled objects
|
||||
*.o
|
||||
*.so
|
||||
|
||||
+34
-2
@@ -1,4 +1,36 @@
|
||||
[submodule "local/sources/base"]
|
||||
path = local/sources/base
|
||||
url = https://gitea.redbearos.org/vasilito/RedBear-OS.git
|
||||
branch = submodule/base
|
||||
[submodule "local/sources/bootloader"]
|
||||
path = local/sources/bootloader
|
||||
url = https://gitea.redbearos.org/vasilito/RedBear-OS.git
|
||||
branch = submodule/bootloader
|
||||
[submodule "local/sources/installer"]
|
||||
path = local/sources/installer
|
||||
url = https://gitea.redbearos.org/vasilito/RedBear-OS.git
|
||||
branch = submodule/installer
|
||||
[submodule "local/sources/kernel"]
|
||||
path = local/sources/kernel
|
||||
url = https://gitea.redbearos.org/vasilito/redbear-os-kernel.git
|
||||
branch = master
|
||||
url = https://gitea.redbearos.org/vasilito/RedBear-OS.git
|
||||
branch = submodule/kernel
|
||||
[submodule "local/sources/libredox"]
|
||||
path = local/sources/libredox
|
||||
url = https://gitea.redbearos.org/vasilito/RedBear-OS.git
|
||||
branch = submodule/libredox
|
||||
[submodule "local/sources/redoxfs"]
|
||||
path = local/sources/redoxfs
|
||||
url = https://gitea.redbearos.org/vasilito/RedBear-OS.git
|
||||
branch = submodule/redoxfs
|
||||
[submodule "local/sources/relibc"]
|
||||
path = local/sources/relibc
|
||||
url = https://gitea.redbearos.org/vasilito/RedBear-OS.git
|
||||
branch = submodule/relibc
|
||||
[submodule "local/sources/syscall"]
|
||||
path = local/sources/syscall
|
||||
url = https://gitea.redbearos.org/vasilito/RedBear-OS.git
|
||||
branch = submodule/syscall
|
||||
[submodule "local/sources/userutils"]
|
||||
path = local/sources/userutils
|
||||
url = https://gitea.redbearos.org/vasilito/RedBear-OS.git
|
||||
branch = submodule/userutils
|
||||
|
||||
+286
-2
@@ -6,6 +6,288 @@ When a commit changes the visible system surface, supported hardware, build flow
|
||||
or major documentation status, add a short note here and keep the README "What's New" section in
|
||||
sync with the newest highlights.
|
||||
|
||||
## 2026-07-01 — Phase I/II complete: full s2idle + S3 entry + LG Gram DMI
|
||||
|
||||
### Phase I.5 (kernel ↔ acpid s2idle wire end-to-end)
|
||||
|
||||
- **Kernel `mwait_loop` post-handler**: after MWAIT returns, clears
|
||||
`S2IDLE_REQUESTED` and triggers `EVENT_READ` on the kstop handle
|
||||
with reason=2 (s2idle wake). Mirrors Linux 7.1
|
||||
`acpi_s2idle_wake` in `drivers/acpi/sleep.c:758`.
|
||||
- **Kernel `kstop` reason codes** (Phase I.5): `KSTOP_FLAG` is now
|
||||
a `u8` with 0=idle, 1=shutdown (S5), 2=s2idle wake, 3=s3 wake.
|
||||
`kstop_set_reason()` and the `CheckShutdown` AcpiVerb return the
|
||||
reason. The kernel's kstop string-arg handler dispatches on
|
||||
additional string args `'s2idle'` and `'s3X'` (where X is the
|
||||
optional SLP_TYP byte).
|
||||
- **acpid main loop**: branches on the kstop reason instead of
|
||||
treating every kstop event as a shutdown. Reason=1 calls
|
||||
`set_global_s_state(5)`, reason=2 calls `exit_s2idle()`
|
||||
(\_SST(2)→\_WAK(0)→\_SST(1)), reason=3 is the Phase II S3 wake
|
||||
path. `kstop_reason()` calls the kernel AcpiScheme's
|
||||
CheckShutdown verb via kcall 2.
|
||||
- **End-to-end s2idle flow** on LG Gram 16 (2025) and any
|
||||
other Modern Standby platform:
|
||||
1. acpid: `enter_s2idle()` (\_TTS(0), \_PTS(0), \_SST(3))
|
||||
2. acpid: write `'s2idle'` to /scheme/sys/kstop
|
||||
3. kernel kstop handler: sets S2IDLE_REQUESTED, returns
|
||||
4. kernel idle path: `mwait_loop()` at deepest C-state
|
||||
5. SCI breaks MWAIT
|
||||
6. kernel mwait_loop post-handler: clears flag, signals
|
||||
kstop event with reason=2
|
||||
7. acpid: `kstop_reason()` returns 2
|
||||
8. acpid: `exit_s2idle()` (\_SST(2)→\_WAK(0)→\_SST(1))
|
||||
9. loop
|
||||
|
||||
### Phase II (S3 entry path)
|
||||
|
||||
- **Kernel FADT parser** (`acpi/fadt.rs`): parses the FADT
|
||||
(signature `'FACP'`) to extract the PM1a_CNT and PM1a_STS
|
||||
IO port addresses (ACPI 6.5 §5.2.9 / Table 5.6). 32-bit
|
||||
General-Purpose Event Register Block 0 Addresses.
|
||||
- **Kernel S3 entry** (`arch/x86_shared/stop.rs::enter_s3`):
|
||||
hardware-agnostic S3 entry path mirroring Linux 7.1
|
||||
`acpi_hw_legacy_sleep` in
|
||||
`drivers/acpi/acpica/hwsleep.c:81-127`. Sequence:
|
||||
1. clear WAK_STS (bit 15 of PM1a_STS)
|
||||
2. flush CPU caches (wbinvd)
|
||||
3. write SLP_TYP to PM1a_CNT
|
||||
4. write SLP_TYP|SLP_EN to PM1a_CNT (split-write for
|
||||
hardware compat)
|
||||
5. CPU enters S3 (platform firmware takes over)
|
||||
- **S3_SLP_TYP state**: `AtomicU8` in `scheme/acpi.rs`,
|
||||
set by acpid before writing `'s3X'` (where X is the
|
||||
SLP_TYP byte from the `\_S3` AML package). Default
|
||||
SLP_TYP=5 (standard for x86 systems). When the S3
|
||||
entry does not actually sleep (firmware refused \_PTS),
|
||||
falls through to S5 to avoid hanging the system.
|
||||
- **Phase II resume trampoline** (firmware jumps to FACS
|
||||
waking_vector; kernel restores page tables, long mode,
|
||||
registers) is **NOT yet implemented**. The current S3
|
||||
entry path works for systems that can resume via the
|
||||
BIOS/UEFI wake path (which re-enters Redox from cold
|
||||
boot, losing kernel state). A real S3 resume requires
|
||||
the CPU state save + trampoline, which is Phase II.X
|
||||
(deferred).
|
||||
- **Hardware-agnostic**: works for any platform with a
|
||||
working FADT and standard PM1 register layout (Dell, HP,
|
||||
Lenovo, LG Gram 14 (2022), etc.). Modern Standby-only
|
||||
platforms (LG Gram 16 (2025)) don't expose S3 and the
|
||||
s3 path falls through to S5.
|
||||
|
||||
### Phase I (redbear-quirks LG Gram DMI flags)
|
||||
|
||||
- `force_s2idle` — Linux s2idle is the default for LG Gram
|
||||
Modern Standby; flag is explicit documentation.
|
||||
- `acpi_irq1_skip_override` — Linux `drivers/acpi/resource.c`
|
||||
`irq1_level_low_skip_override[]` (lines 522-534). Without
|
||||
this the ACPI core rewrites the DSDT's ActiveLow to
|
||||
ActiveHigh and the i8042 keyboard IRQ stops firing.
|
||||
- `kbd_deactivate_fixup` — Linux `drivers/input/keyboard/atkbd.c`
|
||||
line 1913-1917. Prevents spurious keyboard ACK / dropped
|
||||
keys.
|
||||
- `no_legacy_pm1b` — Red Bear OS specific. LG firmware does
|
||||
not implement a separate PM1b_CNT register; tells acpid
|
||||
to skip the SLP_TYPb write path.
|
||||
|
||||
### Phase J (deferred: libredox fork + syscall extension)
|
||||
|
||||
- The `AcpiVerb::EnterS2Idle` and `ExitS2Idle` extensions
|
||||
for the syscall crate are written as a durable overlay
|
||||
patch at `local/patches/syscall/P1-acpiverb-enter-exit-s2idle.patch`.
|
||||
Applied to a local fork of `redox_syscall` at
|
||||
`local/sources/syscall/`. NOT yet wired into the
|
||||
base/kernel `Cargo.toml` `[patch.crates-io]` because
|
||||
`libredox = "0.1.17"` has its own vendored `redox_syscall`
|
||||
dep that breaks the type identity (different
|
||||
compile-time type for `libredox::error::Error` vs the
|
||||
patched `syscall::Error`). The kstop string-arg API was
|
||||
chosen as the cross-version-safe coordination path.
|
||||
|
||||
### Build artifacts
|
||||
|
||||
- `build/x86_64/redbear-mini.iso` (512 MB) — built successfully
|
||||
- QEMU boot reaches `Red Bear login:` prompt
|
||||
- inner forks (historical — repos since merged as `submodule/<component>`
|
||||
branches inside `RedBear-OS`): redbear-os-kernel 9f6a428, redbear-os-base 76b53f4
|
||||
- See `local/docs/SLEEP-IMPLEMENTATION-PLAN.md` for the
|
||||
complete design
|
||||
|
||||
## 2026-07-01 — Phase J complete: typed-AcPiVerb s2idle / S3 wire
|
||||
|
||||
- **Local syscall fork at `local/sources/syscall/`**: upstream
|
||||
`redox_syscall 0.8.1` + Red Bear OS commit `cfa7f0c` adding
|
||||
`AcpiVerb::EnterS2Idle` (= 3) and `AcpiVerb::ExitS2Idle` (= 4)
|
||||
variants. The version field stays at upstream 0.8.1 per the
|
||||
AGENTS.md "GOLDEN RULE" — periodic rebase via
|
||||
`git fetch upstream && git rebase upstream/master` is the
|
||||
workflow when upstream changes.
|
||||
- **Local libredox fork at `local/sources/libredox/`**: upstream
|
||||
`libredox 0.1.17` with the `redox_syscall` dep redirected
|
||||
to `path = "../syscall"`. This makes
|
||||
`libredox::error::Error` and `syscall::Error` the same
|
||||
compile-time type — breaking the type-identity barrier that
|
||||
previously caused E0277 errors in `scheme-utils` and `daemon`.
|
||||
- **base `Cargo.toml`**: `[patch.crates-io] libredox = { path = "../libredox" }`
|
||||
wires the local libredox fork. The existing
|
||||
`[patch.crates-io] redox_syscall = { path = "../syscall" }`
|
||||
is redundant (the base's workspace.dependencies already uses
|
||||
the local path).
|
||||
- **kernel `Cargo.toml`**: `[workspace] members = [".", "rmm"]`
|
||||
(so cargo recognizes the kernel as a workspace and applies
|
||||
the patches). `[patch."https://gitlab.redox-os.org/redox-os/syscall.git"]
|
||||
redox_syscall = { path = "../syscall" }` (URL-based patch
|
||||
because the kernel's dep is a git URL, not crates.io).
|
||||
`[patch.crates-io] libredox = { path = "../libredox" }`.
|
||||
- **Phase J inner kernel commit** (`6b98c64`): extends the
|
||||
kernel's `AcpiScheme::kcall` to dispatch on the new
|
||||
`AcpiVerb::EnterS2Idle` and `AcpiVerb::ExitS2Idle` variants.
|
||||
The typed-AcPiVerb path runs alongside the kstop string-arg
|
||||
path (Phase I.5); both are functional.
|
||||
- **Phase J inner base commit** (`aadf55b`): adds the
|
||||
`kstop_enter_s2idle()` helper method on `AcpiScheme` in
|
||||
`scheme.rs` that wraps the typed-AcPiVerb kcall. The acpid
|
||||
main loop can call this directly.
|
||||
- **Patch file**: `local/patches/syscall/P1-acpiverb-enter-exit-s2idle.patch`
|
||||
is the durable overlay patch backing the syscall fork
|
||||
commit. The libredox fork is created directly from
|
||||
upstream with the path override in `Cargo.toml.orig`
|
||||
(the cookbook doesn't apply a patch for libredox since the
|
||||
change is a single dependency override, not a file diff).
|
||||
- **Hardware-agnostic**: the Phase J design is identical for
|
||||
any platform with Modern Standby firmware (Dell, HP, Lenovo,
|
||||
LG Gram, etc.).
|
||||
- **Build verification**: `redbear-mini.iso` (512 MB) builds
|
||||
successfully with all Phase J commits. The patch system
|
||||
works end-to-end.
|
||||
|
||||
## 2026-07-01 — Phase II.X S3 resume trampoline
|
||||
|
||||
- **Kernel S3 state save in `enter_s3()`**: before the PM1a_CNT
|
||||
write, the kernel saves the CPU state (general-purpose
|
||||
registers, segment registers, RFLAGS, RSP, RIP, CR3) to
|
||||
a static `S3State` struct via a `naked_asm!` block. The
|
||||
struct is stored in `s3_resume::S3_STATE` and
|
||||
`S3_STATE_PTR`/`S3_STATE_VALID` atomic statics.
|
||||
- **Kernel S3 resume trampoline** (`s3_resume::s3_trampoline`):
|
||||
a 64-bit `naked_asm!` block that runs when the platform
|
||||
firmware jumps to FACS.waking_vector on S3 wake. Mirrors
|
||||
Linux 7.1 `arch/x86/kernel/acpi/wakeup_64.S`:
|
||||
- Checks the magic value (0x123456789abcdef0) in
|
||||
S3_STATE.saved_magic. If zero (cold boot), halts.
|
||||
- Restores segment registers to __KERNEL_DS.
|
||||
- Restores CR3 (page table base).
|
||||
- Restores RSP, RFLAGS, 13 general-purpose registers.
|
||||
- Sets the RESUMING_FROM_S3 flag.
|
||||
- Pushes saved RIP onto the stack and uses `ret`.
|
||||
- **Kernel exposes `s3_resume_address()`** that acpid writes
|
||||
to FACS.waking_vector via the kernel AcpiScheme.
|
||||
- **Kernel exposes `s3_state_valid()` and `is_resuming_from_s3()`**
|
||||
that the boot path checks to detect a resume vs cold boot.
|
||||
- **Hardware-agnostic**: works on any x86_64 system with
|
||||
standard ACPI S3 support (Dell, HP, Lenovo, LG Gram 14).
|
||||
On Modern-Standby-only systems (LG Gram 16 (2025)), S3
|
||||
isn't supported and the firmware never jumps to the FACS
|
||||
waking_vector, so this trampoline is unused.
|
||||
- **Build**: redbear-mini.iso (512 MB) builds successfully.
|
||||
The S3 resume path is verified to compile and be present
|
||||
in the ISO. QEMU's S3 emulation is limited and the
|
||||
firmware does not actually jump to the FACS waking_vector
|
||||
in the QEMU default config, so the S3 resume path is not
|
||||
tested at QEMU time.
|
||||
- **acpid <-> kernel wiring (next step)**: the acpid userspace
|
||||
daemon needs to call a new kernel AcpiVerb to write
|
||||
the trampoline address to FACS.waking_vector before
|
||||
\_PTS(3). This is a separate Phase II.X.W commit.
|
||||
|
||||
## 2026-07-01 — Phase II.X.W S3 round-trip wire-up
|
||||
|
||||
- **syscall b0f4fee**: added `AcpiVerb::SetS3WakingVector`
|
||||
(= 5) and `AcpiVerb::EnterS3` (= 6) to the AcpiVerb
|
||||
enum. Hardware-agnostic: works on any x86_64
|
||||
system with standard ACPI S3 support (Dell, HP, Lenovo,
|
||||
LG Gram 14).
|
||||
- **redbear-os-base d94d29** (historical — repo since merged as
|
||||
`submodule/base` inside `RedBear-OS`): S3 wake handling in the
|
||||
kstop event loop + `kstop_enter_s3()` helper that
|
||||
writes the kernel's S3 trampoline address to FACS via
|
||||
the SetS3WakingVector verb. Calls
|
||||
`wake_from_sleep_state(3)` on S3 wake.
|
||||
- **redbear-os-kernel 9bc1fbf**:
|
||||
- **Comprehensive FACS parser** matching Linux 7.1's
|
||||
`struct acpi_table_facs` from `include/acpi/actbl.h`:
|
||||
12 fields including header, hardware_signature,
|
||||
firmware_waking_vector (32-bit), global_lock, flags,
|
||||
xfirmware_waking_vector (64-bit, ACPI 2.0+), version,
|
||||
reserved[3], ospm_flags (ACPI 4.0+), reserved1[24].
|
||||
- **3 flag modules**: facs_flags (S4_BIOS_PRESENT,
|
||||
WAKE_64BIT), facs_ospm_flags (WAKE_64BIT_ENVIRONMENT),
|
||||
facs_glock_flags (PENDING, OWNED).
|
||||
- **FADT.x_firmware_ctrl + firmware_ctrl accessors**:
|
||||
FADT offsets 140 and 36.
|
||||
- **Sdt.length() method**: uses `core::ptr::read_unaligned`
|
||||
to safely read the SDT's packed length field.
|
||||
- **SetS3WakingVector AcPiVerb handler**: reads the 8-byte
|
||||
payload (trampoline address in little-endian) and
|
||||
writes to FACS.xfirmware_waking_vector. A zero payload
|
||||
is a sentinel for "use the kernel's default
|
||||
trampoline address" (s3_trampoline symbol).
|
||||
- **acpi init** (src/acpi/mod.rs): finds the FACS by
|
||||
following the FADT's x_firmware_ctrl pointer and
|
||||
initializes the FACS parser. Logs a warning if FACS
|
||||
is not found.
|
||||
- **Full S3 round-trip flow** is now wired:
|
||||
1. acpid: enter_sleep_state(3) does the AML prep
|
||||
(`_TTS(3)`, `_PTS(3)`, `_SST(3)`)
|
||||
2. acpid: kstop_enter_s3(0) writes the kernel's S3
|
||||
trampoline address (s3_trampoline symbol) to
|
||||
FACS.xfirmware_waking_vector
|
||||
3. acpid: writes 's3' to /scheme/sys/kstop with the
|
||||
SLP_TYP byte
|
||||
4. kernel: stop::enter_s3 reads S3_SLP_TYP, writes
|
||||
SLP_TYP|SLP_EN to PM1a_CNT
|
||||
5. firmware: enters S3
|
||||
6. ... on wake ... firmware jumps to FACS.waking_vector
|
||||
7. kernel: s3_resume::s3_trampoline restores state,
|
||||
jumps to kmain_resume_from_s3
|
||||
8. acpid: receives kstop reason=3, runs
|
||||
wake_from_sleep_state(3) (`_SST(2)` -> `_WAK(3)` ->
|
||||
`_SST(1)`)
|
||||
|
||||
## 2026-07-01 — Build system: explicit patch verification
|
||||
|
||||
The user requested "build system must report complete when
|
||||
upstream have our patches applied". This session adds the
|
||||
explicit verification tools:
|
||||
|
||||
- **`local/scripts/check-cargo-patches.sh`** (Improvement C):
|
||||
For each local source's `Cargo.toml`, scans for
|
||||
`[patch.crates-io]` and `[patch."<URL>"]` sections,
|
||||
resolves the patch via `cargo metadata`, and verifies
|
||||
that the resolved source URL (or manifest_path for
|
||||
path-deps) matches the expected local fork path. Returns
|
||||
non-zero on any unresolved patch. Wraps `cargo metadata`
|
||||
in a 30s timeout to handle large workspaces (relibc,
|
||||
base). Explicitly skips relibc (its `[patch]` is only the
|
||||
cc-rs git branch override, no `path` patches).
|
||||
- **`make verify-patches`**: runs the above script. The
|
||||
current kernel Phase J patch
|
||||
([patch."<URL>"] redox_syscall) is verified
|
||||
end-to-end.
|
||||
- **`make verify-file-patches`**: runs
|
||||
`local/scripts/check-unwired-patches.sh --strict` which
|
||||
verifies all file-level .patch files in `local/patches/`
|
||||
are referenced by at least one recipe.toml `patches = [...]`
|
||||
entry.
|
||||
- **`make verify-all`**: runs both. The comprehensive
|
||||
Phase J end-to-end verification. Returns non-zero on any
|
||||
failure (CI-friendly).
|
||||
|
||||
The cookbook itself already logs `[SUMMARY] All N patches
|
||||
validated successfully` for file-level patches. These new
|
||||
Makefile targets make the verification part of the standard
|
||||
build workflow.
|
||||
|
||||
## 2026-07-01 — cpufreqd oscillation fixed (kernel MSR scheme + VM detection)
|
||||
|
||||
### Kernel fix: `sys` scheme path-strip ENOENT bug (kernel fork commit `c231262`)
|
||||
@@ -379,8 +661,10 @@ versioning"):**
|
||||
`local/AGENTS.md`. Documented the canonical server (gitea.redbearos.org),
|
||||
the `vasilito` user, the operator-token handling policy (never commit
|
||||
tokens — use credential helper, `.netrc`, or `$REDBEAR_GITEA_TOKEN`),
|
||||
the repo map (`vasilito/RedBear-OS`, `vasilito/redbear-os-base`,
|
||||
`vasilito/redbear-os-kernel`, `vasilito/redbear-os-relibc`),
|
||||
the repo map (historical at time of writing — `vasilito/redbear-os-base`,
|
||||
`vasilito/redbear-os-kernel`, `vasilito/redbear-os-relibc`; since merged
|
||||
as `submodule/<component>` branches inside `RedBear-OS` per the
|
||||
SINGLE-REPO RULE in `local/AGENTS.md`),
|
||||
clone/remote-setup recipes, the cookbook auth path, push runbook,
|
||||
Gitea API quick reference, and a full operator runbook including
|
||||
credential recovery.
|
||||
|
||||
@@ -44,6 +44,21 @@ cache-save-essential:
|
||||
cache-verify:
|
||||
@bash $(CACHE_RESTORE) --verify
|
||||
|
||||
# Phase J / Improvement C: verify that all Cargo [patch]
|
||||
# sections in the local sources' Cargo.toml files resolve
|
||||
# to the expected local fork paths. Run after `make all`
|
||||
# to confirm Phase J end-to-end. Returns non-zero exit on
|
||||
# any unresolved patch.
|
||||
verify-patches:
|
||||
@bash local/scripts/check-cargo-patches.sh
|
||||
|
||||
# Phase I: also run the file-level patch check
|
||||
verify-file-patches:
|
||||
@bash local/scripts/check-unwired-patches.sh --strict
|
||||
|
||||
# Verify everything: file-level patches + Cargo [patch] sections
|
||||
verify-all: verify-file-patches verify-patches
|
||||
|
||||
cache-list:
|
||||
@bash $(CACHE_SAVE) --list
|
||||
|
||||
|
||||
+143
-15
@@ -56,6 +56,137 @@ This is the only canonical home for our fork — there is no GitHub / GitLab / C
|
||||
mirror that is treated as authoritative. All Red Bear custom work, including local
|
||||
recipe sources that have no upstream, lives here.
|
||||
|
||||
### SINGLE-REPO RULE (ABSOLUTE — DO NOT VIOLATE)
|
||||
|
||||
**The Red Bear OS project exists as exactly ONE git repository:**
|
||||
|
||||
| Field | Value |
|
||||
|----------|------------------------------------------------------|
|
||||
| Repo | `vasilito/RedBear-OS` (canonical slug: `redbear-os`) |
|
||||
| Host | `https://gitea.redbearos.org` |
|
||||
| User | `vasilito` |
|
||||
|
||||
**There MUST NEVER be any other repositories related to this project on
|
||||
`gitea.redbearos.org`.** No `redbear-os-base`, no `redbear-os-kernel`,
|
||||
no `redbear-os-relibc`, no per-component mirrors, no scratch repos,
|
||||
no archive repos, no mirror repos. Nothing.
|
||||
|
||||
Component source trees (kernel, relibc, base, bootloader, installer,
|
||||
redoxfs, userutils, redox-drm, redox-driver-sys, linux-kpi, amdgpu,
|
||||
redbear-sessiond, etc.) are **NOT separate repositories**. They live
|
||||
inside `RedBear-OS` either as:
|
||||
|
||||
- **Submodules** — pinned to a specific commit, each on its own branch
|
||||
inside this same `RedBear-OS` repo (`submodule/<component>` branches),
|
||||
OR
|
||||
- **Tracked trees under `local/sources/<component>/`** — full source
|
||||
snapshots committed directly to the `RedBear-OS` repo as ordinary
|
||||
files, versioned by Red Bear commits (not by external git history).
|
||||
|
||||
Operators and agents **MUST NOT**:
|
||||
|
||||
- create a new repository on `gitea.redbearos.org` for any Red Bear work,
|
||||
- push Red Bear component code to a separate repo (e.g. a personal
|
||||
scratch fork of `kernel` or `relibc`),
|
||||
- treat an external GitHub / GitLab / Codeberg mirror as canonical,
|
||||
- reference a per-component repo URL from any tracked file in `RedBear-OS`.
|
||||
|
||||
If a recipe's `[source]` section currently points at a separate repo
|
||||
URL (e.g. `https://gitea.redbearos.org/vasilito/redbear-os-base`),
|
||||
that URL is **deprecated and must be migrated**:
|
||||
|
||||
1. Create or reuse a branch inside `RedBear-OS` named
|
||||
`submodule/<component>` (e.g. `submodule/relibc`).
|
||||
2. Push the component's source tree to that branch.
|
||||
3. Replace the recipe's `git = "..."` URL with the in-repo submodule
|
||||
path, and add a `[submodule]` entry referencing the new branch.
|
||||
4. Update `local/AGENTS.md` and any other references.
|
||||
|
||||
**Enforcement.** The cookbook's fetch/validation path treats any
|
||||
component source fetched from outside `RedBear-OS` as a misconfiguration.
|
||||
Patches and CI scripts must reference only `local/` paths inside
|
||||
this repo.
|
||||
|
||||
**Why this rule exists.** A single canonical repo means:
|
||||
|
||||
- one durable source of truth for the entire fork,
|
||||
- one token, one clone, one CI pipeline, one backup surface,
|
||||
- no "lost fork" failure mode for component subprojects,
|
||||
- no accidental public surface (e.g. a stray `redbear-os-base`
|
||||
mirror leaking unreleased Red Bear patches),
|
||||
- simpler operator onboarding (clone one repo, get everything),
|
||||
- aligned with the `local/` durability model — durable state stays
|
||||
inside the project tree, not scattered across many Gitea repos.
|
||||
|
||||
### Migration status (as of 2026-07-01)
|
||||
|
||||
**Migration complete.** Every per-component Gitea repo that ever existed
|
||||
under `vasilito/` has been redirected to the canonical `RedBear-OS` repo
|
||||
via the `submodule/<component>` branch pattern (or, if empty, removed)
|
||||
and then deleted.
|
||||
|
||||
**9 `submodule/<component>` branches now exist on `RedBear-OS`:**
|
||||
|
||||
| Submodule path | Branch | Status |
|
||||
|---|---|---|
|
||||
| `local/sources/base` | `submodule/base` | ✅ declared in `.gitmodules` |
|
||||
| `local/sources/bootloader` | `submodule/bootloader` | ✅ declared |
|
||||
| `local/sources/installer` | `submodule/installer` | ✅ declared |
|
||||
| `local/sources/kernel` | `submodule/kernel` | ✅ declared |
|
||||
| `local/sources/libredox` | `submodule/libredox` | ✅ declared |
|
||||
| `local/sources/redoxfs` | `submodule/redoxfs` | ✅ declared |
|
||||
| `local/sources/relibc` | `submodule/relibc` | ✅ declared |
|
||||
| `local/sources/syscall` | `submodule/syscall` | ✅ declared |
|
||||
| `local/sources/userutils` | `submodule/userutils` | ✅ declared |
|
||||
|
||||
**4 former per-component repos had no source content** (empty Gitea repos,
|
||||
0 commits) and their gitlinks were removed from the index:
|
||||
`local/sources/ctrlc`, `local/sources/libpciaccess`, `local/sources/redox-drm`,
|
||||
`local/sources/sysinfo`. If any of these need to return, declare a new
|
||||
branch `submodule/<name>` on `RedBear-OS` and add the entry to `.gitmodules`.
|
||||
|
||||
**Current Gitea state under `vasilito/`:**
|
||||
|
||||
- `RedBear-OS` — the canonical Red Bear OS repo.
|
||||
- `hiperiso` — unrelated personal project (kept per operator request).
|
||||
|
||||
That is **all**. No other repos.
|
||||
|
||||
### Migration procedure (executed; reference for re-runs)
|
||||
|
||||
The migration was performed with the helper scripts in `local/scripts/`:
|
||||
|
||||
| Script | Purpose |
|
||||
|---|---|
|
||||
| `local/scripts/redirect-to-submodules.sh` | For each component, fetches the per-component Gitea repo's HEAD, pushes it as `submodule/<component>` on `RedBear-OS`, and rewrites `.gitmodules` to point at the new branch. Idempotent. Empty source repos are skipped. |
|
||||
| `local/scripts/delete-per-component-repos.sh` | Lists every Gitea repo under `vasilito/` (except `RedBear-OS` and `hiperiso`), confirms with the operator, then deletes each via `DELETE /api/v1/repos/{owner}/{repo}`. |
|
||||
|
||||
**To re-run for a future component** (e.g. a new per-component repo that
|
||||
someone accidentally creates):
|
||||
|
||||
1. Verify the per-component repo is a Red Bear component, not unrelated.
|
||||
2. `export REDBEAR_GITEA_TOKEN=...` (or set up `~/.netrc`).
|
||||
3. Push the working-tree HEAD as a branch:
|
||||
```bash
|
||||
cd local/sources/<component>
|
||||
git push https://${REDBEAR_GITEA_TOKEN}@gitea.redbearos.org/vasilito/RedBear-OS.git \
|
||||
HEAD:refs/heads/submodule/<component>
|
||||
```
|
||||
4. Declare it in `.gitmodules` (copy an existing entry, change the name + branch).
|
||||
5. `./local/scripts/delete-per-component-repos.sh` to remove the orphaned repo.
|
||||
|
||||
**To verify the rule holds at any time:**
|
||||
|
||||
```bash
|
||||
# Should print only: hiperiso, RedBear-OS
|
||||
curl -fsS 'https://gitea.redbearos.org/api/v1/users/vasilito/repos?limit=200' \
|
||||
| jq -r '.[].name' | sort
|
||||
|
||||
# Should print zero matches (CHANGELOG.md historical entries are exempt)
|
||||
grep -rn 'gitea.redbearos.org/vasilito/redbear-os-' . --include='*.md' \
|
||||
| grep -v 'CHANGELOG.md'
|
||||
```
|
||||
|
||||
### Connection details
|
||||
|
||||
| Field | Value |
|
||||
@@ -84,24 +215,19 @@ recipe sources that have no upstream, lives here.
|
||||
> The actual value lives only on the operator's workstation, in CI
|
||||
> secrets, or in `pass`/`1Password`/`Vault`.
|
||||
|
||||
### Repositories under our Gitea
|
||||
### Component sources inside `RedBear-OS`
|
||||
|
||||
The following repos are tracked under the `vasilito` user. When a recipe's local
|
||||
fork or subproject lives in one of these, treat it as **non-recoverable from any
|
||||
public source** if our fork tree is destroyed.
|
||||
Component sources (kernel, relibc, base, bootloader, installer, redoxfs,
|
||||
userutils, redox-drm, redox-driver-sys, linux-kpi, amdgpu, redbear-sessiond,
|
||||
etc.) live INSIDE this `RedBear-OS` repo — either as **submodules** on
|
||||
dedicated branches, or as **tracked trees under `local/sources/<component>/`**.
|
||||
|
||||
| Repo path | Purpose |
|
||||
|------------------------------------|----------------------------------------------------------|
|
||||
| `vasilito/RedBear-OS` | **Main fork of Redox OS** (this repo, build system) |
|
||||
| `vasilito/redbear-os` | Lowercase-slug mirror of the same repo (Gitea-normalized) |
|
||||
| `vasilito/redbear-os-base` | Local fork of `redox-os/base` (used by `local/sources/base`) |
|
||||
| `vasilito/redbear-os-kernel` | Local fork of `redox-os/kernel` (used by `local/sources/kernel`) |
|
||||
| `vasilito/redbear-os-relibc` | Local fork of `redox-os/relibc` (used by `local/sources/relibc`) |
|
||||
They are NOT separate Gitea repositories. See **SINGLE-REPO RULE** above.
|
||||
|
||||
> **Naming note.** Gitea normalizes repository slugs to lowercase. Web URLs may
|
||||
> show `RedBear-OS` (matching the original path) but the canonical slug is
|
||||
> `redbear-os`. Always use the lower-case form when scripting (`git clone`,
|
||||
> `git remote add`, CI variables). The two rows above refer to the same repo.
|
||||
> `git remote add`, CI variables).
|
||||
|
||||
### How to clone
|
||||
|
||||
@@ -195,9 +321,11 @@ If the server is unreachable:
|
||||
`https://gitea.redbearos.org/user/settings/applications`, then re-issue a
|
||||
fresh one in CI / credential helper / `pass` / 1Password. **Do not** paste the
|
||||
new token into any file in this repo.
|
||||
3. If `local/sources/<component>/` becomes desynced, recover from
|
||||
`https://gitea.redbearos.org/vasilito/redbear-os-<component>` rather than
|
||||
from upstream Redox.
|
||||
3. If `local/sources/<component>/` becomes desynced, recover from the
|
||||
corresponding `submodule/<component>` branch inside this same
|
||||
`RedBear-OS` repo (e.g. `origin/submodule/relibc`) rather than from
|
||||
upstream Redox. Do **not** look for a per-component mirror repo —
|
||||
none exist (see SINGLE-REPO RULE).
|
||||
|
||||
### Recovery from credential loss
|
||||
|
||||
|
||||
@@ -506,10 +506,14 @@ local-fork source tree.
|
||||
|
||||
**Problem.** `local/sources/base/` is a nested git repo (the
|
||||
local-fork model) with `origin = https://gitlab.redox-os.org/redox-os/base.git`.
|
||||
Red Bear's own base fork is at `https://gitea.redbearos.org/vasilito/redbear-os-base`.
|
||||
A Red Bear developer who commits inside `local/sources/base/` and runs
|
||||
`git push origin master` would push Red Bear fork commits **to upstream
|
||||
Redox**, where they will be rejected (or worse, silently fail).
|
||||
**Resolved 2026-07-01:** the Red Bear-specific per-component fork at
|
||||
`vasilito/redbear-os-base` has been migrated to the `submodule/base`
|
||||
branch inside the canonical `RedBear-OS` repo per the SINGLE-REPO RULE
|
||||
(see `local/AGENTS.md`). The base component now lives only as the
|
||||
`submodule/base` branch on `RedBear-OS`. A Red Bear developer who
|
||||
commits inside `local/sources/base/` and runs `git push origin master`
|
||||
would push Red Bear fork commits **to upstream Redox**, where they
|
||||
will be rejected (or worse, silently fail).
|
||||
|
||||
**Current behavior.** Most Red Bear base commits are made by the
|
||||
`Red Bear OS <build@redbearos.org>` author bot during automated syncs, which
|
||||
|
||||
@@ -0,0 +1,763 @@
|
||||
# Red Bear OS — Multi-Threading Comprehensive Assessment and Implementation Plan
|
||||
|
||||
**Date:** 2026-07-02 (initial assessment); 2026-07-02 (Phase 0c patch recovery complete)
|
||||
**Scope:** Full-stack multi-threading audit: hardware/SMP, kernel scheduler, kernel futex, kernel syscall ABI, relibc pthreads, userspace threading correctness and performance
|
||||
**Status:** Authoritative — supersedes `archived/KERNEL-SCHEDULER-MULTITHREAD-IMPROVEMENT-PLAN.md` and `archived/SCHEDULER-REVIEW-FINAL.md` for all threading matters
|
||||
**Validation levels:** `builds` → `enumerates` → `usable` → `validated` → `hardware-validated`
|
||||
|
||||
---
|
||||
|
||||
## UPDATE — Phase 0c Patch Recovery (2026-07-02)
|
||||
|
||||
The assessment in §1 below was accurate as of the time of writing. The Phase 0c
|
||||
patch recovery was then executed in the same session, landing the following
|
||||
commits on the local kernel fork (`local/sources/kernel/`):
|
||||
|
||||
| Commit | Effect |
|
||||
|--------|--------|
|
||||
| `ed3f0e1` | **P6-futex-sharding**: replaces single global `Mutex<L1, FutexList>` with 64-shard hash table |
|
||||
| `5fb42fc` | **RUN_QUEUE_COUNT pre-flight**: defines `pub const RUN_QUEUE_COUNT: usize = 40;` (was missing from patch chain) |
|
||||
| `cbf051e` | **P7-cache-affine-context (manual)**: surgically inserts `SchedPolicy` enum, `SCHED_PRIORITY_LEVELS`, helper functions, and 9 new Context fields (last_cpu, sched_policy, sched_rt_priority, sched_rr_ticks_consumed, sched_static_prio, sched_rr_quantum, vruntime, futex_pi_*, PhysicalAddress import) |
|
||||
| `f7652fc` | **P5-context-mod-sched + P8-percpu-sched + P8-percpu-wiring**: PerCpuSched struct with SyncUnsafeCell-wrapped per-CPU run queues, get_percpu_block helper, full per-CPU scheduler wiring in switch.rs (pick_next_from_queues, pick_next_from_global_queues, select_next_context) |
|
||||
| `7fc8bbf` | **P8-initial-placement + P9-numa-topology + P9-proc-lock-ordering**: least-loaded-CPU spawn, NUMA topology hints, proc scheme lock order fix |
|
||||
| `327c150` | **`set_sched_policy` + `set_sched_other_prio`**: missing Context methods called by proc scheme handles |
|
||||
| `e8ec916` | **fadt usize/u32 type mismatch fix**: changes FADT_MIN_SIZE constants to `u32` to match `Sdt::length()` |
|
||||
| `4789d54` | **SchedPolicy/Name/Priority proc scheme handles**: adds `/proc/<tid>/{name, sched-policy, priority}` paths and read/write handlers |
|
||||
|
||||
**Upstream check (bg_27f3578a, 2026-07-02):** verified that `gitlab.redox-os.org/redox-os/kernel`
|
||||
master (commit `aa7e7d2f44ba7cd9d1b007d37db139b345d46b8a`) has **NONE** of these features. The
|
||||
local fork is the sole implementation. No upstream cherry-picks are available.
|
||||
|
||||
**Plan-vs-actual state:**
|
||||
|
||||
| Plan claim (Section 1) | Actual state after Phase 0c |
|
||||
|---|---|
|
||||
| "Baseline DWRR scheduler only (no per-CPU queues, no work stealing, no load balancing, no vruntime, no RT scheduling, no cache-affine)" | ✅ All 5 features now present. Per-CPU `PerCpuSched` with `run_queues`, `steal_work()`, `migrate_one_context()`, `maybe_balance_queues()`, `vruntime` CFS-style weighting, `last_cpu` cache-affine vruntime bonus, `SchedPolicy::Fifo`/`RoundRobin` RT scanning in `pick_next_from_queues` |
|
||||
| "Baseline futex only (WAIT/WAIT64/WAKE — no sharding, no PI, no REQUEUE, no robust, no WAKE_OP, no BITSET)" | 🟡 **Sharding done** (64-shard hash). REQUEUE/PI/robust/WAKE_OP/BITSET still missing. |
|
||||
| "relibc `sched_*` are all `todo!()`, `pthread_setschedparam` is a no-op, robust mutexes are `todo_skip!`, PI is absent" | 🟡 relibc fork only has the `pthread_cond_signal` POSIX fix so far. `sched_*`, robust, PI still pending in relibc. |
|
||||
| "❌ Missing from relibc: CPU affinity API, Thread naming" | 🟡 **Kernel side done** — `/proc/<tid>/{sched-policy, name, priority}` handles. relibc pthread_setname_np / pthread_setaffinity_np / sched_setscheduler still pending. |
|
||||
| "cargo check has 1 pre-existing error" | ✅ **Fixed** — `cargo check` now exits 0 with 0 errors. |
|
||||
|
||||
**Phase 0c status: kernel side complete (all 8 of 8 applicable kernel P5–P9 patches
|
||||
re-applied or made obsolete by the existing refactored scheduler). Remaining work
|
||||
is in the relibc fork (Phase 0e) and the futex-REQUEUE/PI/robust work (Phase 1).**
|
||||
|
||||
The detailed analysis in §1–§9 below is preserved as historical record. The status
|
||||
column "🚧 Missing" in §1 should be re-read as "now present in the local kernel
|
||||
fork, pending relibc userspace wiring."
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
## 1. Executive Summary
|
||||
|
||||
### The Critical Finding — Lost Threading Work
|
||||
|
||||
The P5–P9 scheduler and futex enhancement work (documented as "complete" in the archived
|
||||
plans) was **lost during the local fork migration** (2026-06). The local forks at
|
||||
`local/sources/kernel/` and `local/sources/relibc/` were created from **upstream Redox
|
||||
baselines** that did NOT include the Red Bear enhancement patches. The patches exist in
|
||||
`local/patches/kernel/` and `local/patches/relibc/` but are **not wired into the recipes**
|
||||
(both `recipe.toml` files use `path = "..."` with no `patches = [...]` list).
|
||||
|
||||
**Impact:** The running kernel has:
|
||||
- Baseline DWRR scheduler only (no per-CPU queues, no work stealing, no load balancing, no vruntime, no RT scheduling, no cache-affine)
|
||||
- Baseline futex only (WAIT/WAIT64/WAKE — no sharding, no PI, no REQUEUE, no robust, no WAKE_OP, no BITSET)
|
||||
- relibc `sched_*` are all `todo!()`, `pthread_setschedparam` is a no-op, robust mutexes are `todo_skip!`, PI is absent
|
||||
|
||||
**Recovery:** 13 of 18 kernel P5–P9 patches apply cleanly to the current fork. 5 fail due to
|
||||
patch-chain dependencies (they expect earlier patches applied first). The bulk of the work is
|
||||
recoverable by re-applying patches to the forks and committing them.
|
||||
|
||||
### What Actually Works Today
|
||||
|
||||
| Layer | Status | Detail |
|
||||
|-------|--------|--------|
|
||||
| **SMP boot** | ✅ Solid | INIT→SIPI sequence correct, per-CPU PCR via GS_BASE, x2APIC support |
|
||||
| **Context switching** | ✅ Solid | FPU/SIMD/AVX state save via XSAVE, FSBASE/GSBASE swap (FSGSBASE or MSR), correct callee-saved register save |
|
||||
| **TLB shootdown protocol** | ✅ Correct | AtomicBool flag + IPI + ack counter with `fence(SeqCst)` race prevention |
|
||||
| **Basic thread lifecycle** | ✅ Functional | pthread_create/join/detach/exit through proc scheme + redox_rt clone |
|
||||
| **Basic synchronization** | ✅ Functional | Futex-backed mutex, condvar, rwlock, barrier, spinlock, once |
|
||||
| **TLS** | ✅ Functional | ELF PT_TLS + pthread_key_create/getspecific/setspecific |
|
||||
| **Per-CPU data** | ✅ Functional | PercpuBlock via GS_BASE, all per-CPU state accessible |
|
||||
| **Signal delivery** | ✅ Functional | Shared-memory Sigcontrol pages, per-thread masks, trampoline |
|
||||
| **Scheduler algorithm** | 🚧 Basic DWRR | 40 priority levels, geometric weights, cooperative preemption (3-tick quantum) |
|
||||
| **Futex operations** | 🚧 Basic only | WAIT/WAIT64/WAKE with single global mutex |
|
||||
| **SMP load balancing** | ❌ Missing | No work stealing, no migration, contexts stuck on birth CPU |
|
||||
| **RT scheduling** | ❌ Missing | No SCHED_FIFO/SCHED_RR, no kernel policy dispatch |
|
||||
| **Futex REQUEUE** | ❌ Missing | Condvar broadcast causes thundering herd |
|
||||
| **Robust mutexes** | ❌ Missing | Thread death while holding mutex → permanent deadlock |
|
||||
| **PI futexes** | ❌ Missing | No priority inheritance → priority inversion risk |
|
||||
| **CPU affinity API** | ❌ Missing from relibc | Kernel supports sched_affinity field but no userspace API |
|
||||
| **Thread naming** | ❌ Missing from relibc | Kernel supports name field but no userspace API |
|
||||
| **Per-page TLB flush** | ❌ Missing | `invalidate_all()` = full CR3 reload on every shootdown |
|
||||
| **NUMA awareness** | ❌ Missing | No SRAT/SLIT, no proximity domains, flat memory model |
|
||||
| **IRQ balancing** | ❌ Missing | All legacy IRQs hardwired to BSP |
|
||||
|
||||
---
|
||||
|
||||
## 2. Layer-by-Layer Assessment
|
||||
|
||||
### 2.1 Hardware / SMP Layer
|
||||
|
||||
**Files:** `src/acpi/madt/arch/x86.rs`, `src/arch/x86_shared/start.rs`,
|
||||
`src/arch/x86_shared/device/local_apic.rs`, `src/arch/x86_shared/device/ioapic.rs`,
|
||||
`src/arch/x86_shared/ipi.rs`, `src/arch/x86_shared/interrupt/ipi.rs`, `src/percpu.rs`,
|
||||
`src/arch/x86_shared/gdt.rs`
|
||||
|
||||
**Verdict: Functional foundation, performance gaps.**
|
||||
|
||||
| Component | Status | Detail |
|
||||
|-----------|--------|--------|
|
||||
| AP boot (INIT/SIPI) | ✅ validated | Correct trampoline at 0x8000, per-AP PCR/IDT/stack allocation |
|
||||
| x2APIC mode | ✅ builds | Detected via CPUID, MSR-based access, APIC ID detection |
|
||||
| Per-CPU PCR via GS_BASE | ✅ validated | `PercpuBlock::current()` reads from PCR, SWAPGS protocol correct |
|
||||
| IPI send/receive | ✅ functional | 5 IPI kinds (Wakeup/Tlb/Switch/Pit/Profile), broadcast + unicast |
|
||||
| TLB shootdown | ✅ correct | AtomicBool + IPI + ack with `fence(SeqCst)` race prevention |
|
||||
| TLB granularity | ❌ coarse | Full CR3 reload (`mov cr3, cr3`) on every shootdown — no INVLPG |
|
||||
| TLB broadcast | 🚧 sequential | Iterates CPUs individually, doesn't use ICR "all excluding self" shorthand |
|
||||
| IRQ routing | ❌ BSP-only | Legacy I/O APIC entries hardcode `dest: bsp_apic_id` |
|
||||
| NUMA | ❌ absent | No SRAT/SLIT, no proximity domains |
|
||||
| SMT/HT topology | ❌ absent | No cache hierarchy, no hyperthread awareness |
|
||||
| Idle loop | ✅ functional | MWAIT with deepest C-state or HLT fallback |
|
||||
| W^X for trampoline | 🚧 minor | Trampoline page briefly W+X, unmapped after AP boot |
|
||||
|
||||
### 2.2 Kernel Scheduler Layer
|
||||
|
||||
**Files:** `src/context/switch.rs`, `src/context/mod.rs`, `src/context/context.rs`,
|
||||
`src/context/timeout.rs`
|
||||
|
||||
**Verdict: Correct but primitive — DWRR only, no SMP balancing, no RT classes.**
|
||||
|
||||
**Algorithm:** Deficit Weighted Round Robin (DWRR)
|
||||
- 40 priority levels, each a `VecDeque<WeakContextRef>`
|
||||
- Geometric weights: `SCHED_PRIO_TO_WEIGHT[i] ≈ 1.25^i` (88761 → 15)
|
||||
- Per-CPU `balance` accumulator drives dequeue decisions
|
||||
- Quantum: 3 PIT ticks (~12.2ms) per scheduling round
|
||||
- Cooperative preemption: `preempt_locks > 0` disables preemption
|
||||
|
||||
**Global locks:**
|
||||
- `RUN_CONTEXTS: Mutex<L1, RunContextData>` — all 40 priority queues under one L1 lock
|
||||
- `IDLE_CONTEXTS: Mutex<L2, VecDeque<WeakContextRef>>` — sleeping contexts
|
||||
- `CONTEXT_SWITCH_LOCK: AtomicBool` — global CAS spinlock serializing all context switches
|
||||
|
||||
**What's missing (all was in lost P5–P9 work):**
|
||||
|
||||
| Gap | Lost Patch | Recoverable? |
|
||||
|-----|-----------|-------------|
|
||||
| Per-CPU run queues (eliminate global L1) | P6-percpu-runqueues, P8-percpu-sched, P8-percpu-wiring | ✅ applies cleanly |
|
||||
| Work stealing | P8-work-stealing | ❌ needs rebase (depends on per-CPU wiring) |
|
||||
| Initial placement (least-loaded CPU) | P8-initial-placement | ✅ applies cleanly |
|
||||
| Load balancing | P8-load-balance (absorbed) | needs verification |
|
||||
| Vruntime tracking + min-vruntime selection | P6-vruntime-switch | ✅ applies cleanly |
|
||||
| SchedPolicy enum (FIFO/RR/Other) | P5-sched-rt-policy | ✅ applies cleanly |
|
||||
| RT scheduling dispatch | P5-sched-rt-policy | ✅ applies cleanly |
|
||||
| Cache-affine scheduling | P7-cache-affine-switch | ✅ applies cleanly |
|
||||
| NUMA topology hints | P9-numa-topology | ✅ applies cleanly |
|
||||
|
||||
### 2.3 Kernel Futex Layer
|
||||
|
||||
**File:** `src/syscall/futex.rs`
|
||||
|
||||
**Verdict: Baseline only — critical operations missing for desktop workloads.**
|
||||
|
||||
| Operation | Status | Impact of Absence |
|
||||
|-----------|--------|-------------------|
|
||||
| `FUTEX_WAIT` (32-bit) | ✅ | — |
|
||||
| `FUTEX_WAIT64` (64-bit) | ✅ | — |
|
||||
| `FUTEX_WAKE` | ✅ | — |
|
||||
| `FUTEX_REQUEUE` | ❌ returns EINVAL | `pthread_cond_broadcast` wakes ALL waiters (thundering herd) |
|
||||
| `FUTEX_CMP_REQUEUE` | ❌ not defined | Same + atomicity gap |
|
||||
| `FUTEX_WAKE_OP` | ❌ not defined | glibc mutex fast path unavailable |
|
||||
| `FUTEX_WAIT_BITSET` | ❌ not defined | `pselect`/`ppoll` optimization unavailable |
|
||||
| `FUTEX_WAKE_BITSET` | ❌ not defined | Targeted wake unavailable |
|
||||
| `FUTEX_LOCK_PI` / `UNLOCK_PI` | ❌ not defined | Priority inversion unprotected |
|
||||
| Robust futex list | ❌ not defined | Thread death → permanent deadlock |
|
||||
| Futex sharding (per-futex lock) | ❌ single global L1 mutex | All futex ops on all CPUs contend on one lock |
|
||||
| Process-private futexes | ❌ global table | Unnecessary cross-process visibility |
|
||||
|
||||
**Architecture:**
|
||||
```
|
||||
static FUTEXES: Mutex<L1, FutexList> // single global lock
|
||||
type FutexList = HashMap<PhysicalAddress, Vec<FutexEntry>>
|
||||
```
|
||||
|
||||
Physical address is the key (enables cross-address-space futex via MAP_SHARED).
|
||||
Virtual address + Weak<AddrSpaceWrapper> used for CoW disambiguation.
|
||||
|
||||
**Recoverable work (lost patches):**
|
||||
|
||||
| Feature | Lost Patch | Applies? |
|
||||
|---------|-----------|----------|
|
||||
| 64-shard hash table | P6-futex-sharding | ✅ cleanly |
|
||||
| FUTEX_REQUEUE + CMP_REQUEUE | P8-futex-requeue | ❌ needs rebase |
|
||||
| PI futex (LOCK_PI/UNLOCK_PI/TRYLOCK_PI) | P8-futex-pi | ❌ needs rebase |
|
||||
| PI CAS fix | P9-futex-pi-cas-fix | ❌ needs rebase |
|
||||
| Robust futex list | P8-futex-robust | ❌ needs rebase |
|
||||
|
||||
The 4 failing patches likely fail because they depend on sharding (P6-futex-sharding) being
|
||||
applied first. Apply in order: P6-sharding → P8-requeue → P8-pi → P8-robust → P9-pi-cas-fix.
|
||||
|
||||
### 2.4 Kernel Syscall ABI Layer
|
||||
|
||||
**Files:** `src/syscall/mod.rs`, `src/syscall/futex.rs`, `src/syscall/time.rs`,
|
||||
`src/syscall/process.rs`, `local/sources/syscall/src/number.rs`, `src/scheme/proc.rs`
|
||||
|
||||
**Verdict: Minimal surface — most threading done via proc scheme, not syscalls.**
|
||||
|
||||
The kernel defines only ~35 syscall numbers. Threading-relevant ones:
|
||||
|
||||
| Syscall | Status | Notes |
|
||||
|---------|--------|-------|
|
||||
| `SYS_FUTEX` (240) | ✅ partial | WAIT/WAIT64/WAKE only |
|
||||
| `SYS_YIELD` (158) | ✅ | `context::switch()` + signal handler |
|
||||
| `SYS_FMAP` (900) | ✅ | Anonymous + file-backed mmap |
|
||||
| `SYS_FUNMAP` (92) | ✅ | munmap |
|
||||
| `SYS_MPROTECT` (125) | ✅ | |
|
||||
| `SYS_MREMAP` (155) | ✅ | |
|
||||
| `SYS_NANOSLEEP` (162) | ✅ | EINTR-aware |
|
||||
| `SYS_CLOCK_GETTIME` (265) | ✅ partial | REALTIME + MONOTONIC only |
|
||||
|
||||
**Threading done via proc scheme (not syscalls):**
|
||||
|
||||
| Operation | Mechanism |
|
||||
|-----------|-----------|
|
||||
| Thread/process creation | `proc:` scheme: open "new-context", share addr_space + files via kdup |
|
||||
| waitpid | `proc:` scheme: `EVENT_READ` on context fd |
|
||||
| getpid/gettid | `proc:` scheme: read "attrs" handle |
|
||||
| kill/tkill | `proc:` scheme: `ForceKill` / `Interrupt` ContextVerb |
|
||||
| CPU affinity | `proc:` scheme: write "sched-affinity" handle |
|
||||
| Priority | `proc:` scheme: write "attrs" prio field |
|
||||
| Signal setup | `proc:` scheme: write "sighandler" + shared Sigcontrol pages |
|
||||
| TLS base (FSBASE) | `proc:` scheme: write "regs/env" EnvRegisters |
|
||||
|
||||
**Completely missing syscalls (no number, no handler):**
|
||||
`clone`, `fork`, `vfork`, `waitpid`, `wait4`, `kill`, `tkill`, `tgkill`, `arch_prctl`,
|
||||
`set_thread_area`, `set_tid_address`, `set_robust_list`, `get_robust_list`,
|
||||
`sched_setaffinity`, `sched_getaffinity`, `sched_setscheduler`, `sched_getparam`,
|
||||
`sigaction`, `sigprocmask`, `sigpending`, `sigsuspend`, `sigtimedwait`,
|
||||
`timer_create`, `timer_settime`, `timer_delete`, `timerfd_create`,
|
||||
`getrusage`, `setrlimit`, `getrlimit`, `times`
|
||||
|
||||
### 2.5 relibc Pthread Layer
|
||||
|
||||
**Files:** `src/pthread/mod.rs`, `src/sync/*.rs`, `src/header/pthread/*.rs`,
|
||||
`src/header/sched/mod.rs`, `src/ld_so/tcb.rs`, `src/platform/redox/mod.rs`
|
||||
|
||||
**Verdict: Core pthreads solid, scheduling/robust/PI absent, several POSIX gaps.**
|
||||
|
||||
#### Fully Working (futex-backed)
|
||||
|
||||
| API Group | Backend | Notes |
|
||||
|-----------|---------|-------|
|
||||
| `pthread_create/join/detach/exit` | redox_rt clone + Waitval | Stack via mmap, TLS via Tcb::new() |
|
||||
| `pthread_cancel/setcancelstate/testcancel` | SIGRT_RLCT_CANCEL (33) | Deferred cancellation only |
|
||||
| `pthread_mutex_*` (normal/recursive/errorcheck) | AtomicU32 CAS + futex_wait/wake | 3-state: unlocked/locked/waiters |
|
||||
| `pthread_cond_*` | Two-counter futex design | CLOCK_REALTIME only (monotonic = stub) |
|
||||
| `pthread_rwlock_*` | AtomicU32 + futex | Reader count + WAITING_WR bit |
|
||||
| `pthread_barrier_*` | Mutex + Cond | gen_id wrapping counter |
|
||||
| `pthread_spin_*` | AtomicI32 CAS | No futex, pure spinning |
|
||||
| `pthread_once` | 3-state futex (UNINIT→INITING→INIT) | |
|
||||
| `pthread_key_create/getspecific/setspecific/delete` | BTreeMap global + thread_local values | Destructor iteration per POSIX |
|
||||
| `pthread_sigmask` | Delegates to sigprocmask | |
|
||||
| `pthread_kill` | redox_rt::rlct_kill | |
|
||||
| `pthread_atfork` | Thread-local LinkedList hooks | |
|
||||
| ELF TLS (`__thread` / `#[thread_local]`) | PT_TLS + Tcb | Static + dynamic DTV for dlopen |
|
||||
| `pthread_attr_*` (getters/setters) | RlctAttr struct | |
|
||||
|
||||
#### Stubs / No-ops / Missing
|
||||
|
||||
| API | Status | Root Cause |
|
||||
|-----|--------|------------|
|
||||
| `sched_get_priority_max/min` | `todo!()` | Kernel has no scheduling policy API |
|
||||
| `sched_getparam/setparam` | `todo!()` | Same |
|
||||
| `sched_setscheduler` | `todo!()` | Same |
|
||||
| `sched_rr_get_interval` | `todo!()` | Same |
|
||||
| `pthread_setschedparam` | No-op (returns Ok) | Kernel ignores policy |
|
||||
| `pthread_setschedprio` | No-op (returns Ok) | Kernel ignores priority change |
|
||||
| `pthread_getschedparam` | `todo!()` | |
|
||||
| `pthread_getcpuclockid` | ENOENT | No per-thread CPU clock |
|
||||
| `pthread_mutex_consistent` | `todo_skip!` | Robust mutex not implemented |
|
||||
| `pthread_mutex_getprioceiling` | `todo_skip!` | Priority ceiling not implemented |
|
||||
| `pthread_mutex_setprioceiling` | `todo_skip!` | Same |
|
||||
| `pthread_mutexattr_setprotocol` (PRIO_INHERIT) | Accepted, no-op | PI futex missing |
|
||||
| `pthread_mutexattr_setrobust` (ROBUST) | Accepted, no-op | Robust futex missing |
|
||||
| `pthread_cond_init` CLOCK_MONOTONIC | `todo_skip!` | |
|
||||
| `pthread_cond_signal` | Calls broadcast (wakes ALL) | Missing FUTEX_REQUEUE optimization |
|
||||
| `pthread_setaffinity_np` | Not defined | |
|
||||
| `pthread_getaffinity_np` | Not defined | |
|
||||
| `pthread_setname_np` | Not defined | |
|
||||
| `pthread_getname_np` | Not defined | |
|
||||
| `pthread_setcanceltype` | Always returns DEFERRED | ASYNC not tracked |
|
||||
| Guard pages | Attribute stored, not mapped | No PROT_NONE page before stack |
|
||||
| PTHREAD_KEYS_MAX limit | Not checked | |
|
||||
|
||||
---
|
||||
|
||||
## 3. Gap Classification
|
||||
|
||||
### 3.1 Correctness Gaps (Must Fix — Silent Data Corruption or Deadlock)
|
||||
|
||||
| # | Gap | Impact | Fix Location |
|
||||
|---|-----|--------|-------------|
|
||||
| C1 | **No robust mutexes** | Thread death while holding mutex → permanent deadlock for all waiters | Kernel: robust futex list + relibc: pthread_mutex_consistent |
|
||||
| C2 | **No PI futexes** | Priority inversion: low-prio thread blocks high-prio thread indefinitely | Kernel: FUTEX_LOCK_PI/UNLOCK_PI + relibc: mutexattr_setprotocol |
|
||||
| C3 | **`pthread_cond_signal` wakes ALL** | Correctness: wastes CPU. Performance: thundering herd on every signal | relibc: use true wake(1) — may need FUTEX_REQUEUE |
|
||||
| C4 | **`fork()` not thread-safe** | `pthread_atfork` hooks exist but child inherits locked mutexes | relibc: implement atfork child handlers properly |
|
||||
|
||||
### 3.2 Performance Gaps (Must Fix for Desktop Responsiveness)
|
||||
|
||||
| # | Gap | Impact | Fix Location |
|
||||
|---|-----|--------|-------------|
|
||||
| P1 | **No SMP load balancing** | Cores sit idle while others are overloaded | Kernel: work stealing + initial placement |
|
||||
| P2 | **No futex sharding** | Single global L1 mutex for ALL futex ops on ALL CPUs | Kernel: 64-shard hash table |
|
||||
| P3 | **No FUTEX_REQUEUE** | `pthread_cond_broadcast` wakes all → thundering herd | Kernel: REQUEUE + CMP_REQUEUE |
|
||||
| P4 | **Full TLB flush on every shootdown** | Per-page mprotect/munmap flushes entire TLB on all cores | Kernel: INVLPG-based selective flush |
|
||||
| P5 | **Global context switch lock** | Serialization bottleneck beyond ~8 cores | Kernel: per-CPU context switch (needs per-CPU run queues) |
|
||||
| P6 | **All IRQs to BSP** | CPU 0 handles all interrupts, cache thrash, latency | Kernel: IRQ steering in I/O APIC + MSI/MSI-X dest field |
|
||||
| P7 | **No RT scheduling** | Audio/compositor threads can't get priority | Kernel: SchedPolicy + RT dispatch + relibc: sched_setscheduler |
|
||||
|
||||
### 3.3 POSIX Completeness Gaps (Must Fix for Application Compatibility)
|
||||
|
||||
| # | Gap | Impact | Fix Location |
|
||||
|---|-----|--------|-------------|
|
||||
| X1 | `sched_*` all `todo!()` | Applications calling sched_setscheduler panic | relibc: implement via proc scheme |
|
||||
| X2 | `pthread_setschedparam` no-op | Apps can't change thread priority | relibc: wire to proc scheme prio write |
|
||||
| X3 | `pthread_setaffinity_np` missing | Apps can't pin threads to CPUs | relibc: implement via proc scheme affinity write |
|
||||
| X4 | `pthread_setname_np` missing | Debugging harder (no thread names in /proc) | relibc: implement via proc scheme name write |
|
||||
| X5 | `pthread_getcpuclockid` ENOENT | Per-thread profiling impossible | relibc + kernel: expose cpu_time via clock |
|
||||
| X6 | Guard pages not mapped | Stack overflow → silent corruption, no SIGSEGV | relibc: mmap PROT_NONE guard page in pthread_create |
|
||||
| X7 | `pthread_cond_init` monotonic stub | CLOCK_MONOTONIC condvars use REALTIME (affected by wall clock jumps) | relibc: implement monotonic condvar |
|
||||
|
||||
---
|
||||
|
||||
## 4. Implementation Plan
|
||||
|
||||
### Phase 0: Patch Recovery — Re-Apply Lost Threading Work (Week 1–2)
|
||||
|
||||
**Goal:** Recover the P5–P9 work that was lost during the local fork migration.
|
||||
|
||||
**This is the highest-priority phase — it restores ~6 months of work with minimal new code.**
|
||||
|
||||
#### 0.1 — Re-apply kernel scheduler patches to local fork
|
||||
|
||||
Apply in dependency order to `local/sources/kernel/`:
|
||||
|
||||
| Order | Patch | Status | Action |
|
||||
|-------|-------|--------|--------|
|
||||
| 1 | P6-futex-sharding | ✅ applies | Commit directly |
|
||||
| 2 | P6-percpu-runqueues | ✅ applies | Commit directly |
|
||||
| 3 | P8-percpu-sched | ✅ applies | Commit directly |
|
||||
| 4 | P8-percpu-wiring | ✅ applies | Commit directly |
|
||||
| 5 | P8-initial-placement | ✅ applies | Commit directly |
|
||||
| 6 | P5-sched-rt-policy | ✅ applies | Commit directly |
|
||||
| 7 | P5-context-mod-sched | ✅ applies | Commit directly |
|
||||
| 8 | P6-vruntime-switch | ✅ applies | Commit directly |
|
||||
| 9 | P7-cache-affine-switch | ✅ applies | Commit directly |
|
||||
| 10 | P9-numa-topology | ✅ applies | Commit directly |
|
||||
| 11 | P9-proc-lock-ordering | ✅ applies | Commit directly |
|
||||
| 12 | P8-work-stealing | ❌ needs rebase | Rebase against 1–11, then apply |
|
||||
| 13 | P8-futex-requeue | ❌ needs rebase | Rebase against P6-sharding (#1), then apply |
|
||||
| 14 | P8-futex-pi | ❌ needs rebase | Rebase against #13, then apply |
|
||||
| 15 | P8-futex-robust | ❌ needs rebase | Rebase against #14, then apply |
|
||||
| 16 | P9-futex-pi-cas-fix | ❌ needs rebase | Rebase against #14, then apply |
|
||||
| 17 | P7-scheduler-improvements | ❌ needs rebase | Rebase against 1–11, then apply |
|
||||
|
||||
**Verification after each patch:**
|
||||
```bash
|
||||
cd local/sources/kernel
|
||||
cargo check # must pass
|
||||
```
|
||||
|
||||
#### 0.2 — Re-apply relibc threading patches to local fork
|
||||
|
||||
Apply to `local/sources/relibc/`:
|
||||
|
||||
| Patch | Action |
|
||||
|-------|--------|
|
||||
| P3-threads.patch | ✅ applies — commit |
|
||||
| P3-barrier-smp-futex (from absorbed/) | Verify already in fork; if not, apply |
|
||||
| P3-pthread-signal-races (from absorbed/) | Verify already in fork |
|
||||
| P3-pthread-yield (from absorbed/) | Verify already in fork |
|
||||
| P5-robust-mutexes (from absorbed/) | Verify; re-apply if missing |
|
||||
| P5-robust-mutex-enotrec-fix (from absorbed/) | Same |
|
||||
| P5-sched-api (from absorbed/) | Same |
|
||||
| P7-pthread-affinity (from absorbed/) | Same |
|
||||
| P7-pthread-setname (from absorbed/) | Same |
|
||||
| P7-setpriority (from absorbed/) | Same |
|
||||
| P9-spin-and-barrier (from absorbed/) | Same |
|
||||
| P9-spin-fix (from absorbed/) | Same |
|
||||
| P3-semaphore-comprehensive | ✅ applies |
|
||||
|
||||
**Verification:**
|
||||
```bash
|
||||
cd local/sources/relibc
|
||||
make all # must pass
|
||||
touch relibc && make prefix # rebuild prefix with new libc
|
||||
```
|
||||
|
||||
#### 0.3 — Build and smoke test
|
||||
|
||||
```bash
|
||||
export REDBEAR_ALLOW_PROTECTED_FETCH=1
|
||||
./local/scripts/build-redbear.sh --upstream redbear-mini
|
||||
make qemu # verify boot + basic operation
|
||||
```
|
||||
|
||||
**Success criteria:** redbear-mini boots, multi-threaded daemons (pcid, xhcid) start, no kernel panic.
|
||||
|
||||
---
|
||||
|
||||
### Phase 1: Futex Completeness (Week 2–4)
|
||||
|
||||
**Goal:** Close the futex operation gaps that affect correctness and performance.
|
||||
|
||||
**Depends on:** Phase 0 complete (sharding applied first).
|
||||
|
||||
#### 1.1 — FUTEX_REQUEUE + FUTEX_CMP_REQUEUE
|
||||
|
||||
**Kernel:** `src/syscall/futex.rs`
|
||||
- Add `FUTEX_REQUEUE` and `FUTEX_CMP_REQUEUE` to the futex dispatcher
|
||||
- Implement: move up to `val` waiters from addr1 → addr2, optionally compare `*addr1 == val2`
|
||||
- Requires locking TWO shards (acquire both in deterministic order to avoid deadlock)
|
||||
|
||||
**relibc:** `src/sync/cond.rs`
|
||||
- Change `pthread_cond_broadcast` to use `FUTEX_REQUEUE` (move waiters from condvar futex to mutex futex)
|
||||
- Change `pthread_cond_signal` to wake exactly 1 (not all)
|
||||
|
||||
**Impact:** Eliminates thundering herd on every `pthread_cond_broadcast`. Major win for Qt event loop, KWin compositor, Mesa worker threads.
|
||||
|
||||
#### 1.2 — PI Futexes (FUTEX_LOCK_PI / FUTEX_UNLOCK_PI / FUTEX_TRYLOCK_PI)
|
||||
|
||||
**Kernel:** `src/syscall/futex.rs`
|
||||
- Add `PiState` tracking per futex: owner context + waiter list with priorities
|
||||
- On `LOCK_PI` block: boost owner's priority to waiter's priority
|
||||
- On `UNLOCK_PI`: restore original priority, wake highest-priority waiter
|
||||
- Requires kernel RT scheduling (Phase 0.1 #6–7: P5-sched-rt-policy)
|
||||
|
||||
**relibc:** `src/sync/pthread_mutex.rs`
|
||||
- Implement `PTHREAD_PRIO_INHERIT` protocol path using PI futex
|
||||
- Replace `todo_skip!` in `pthread_mutex_consistent` with real implementation
|
||||
|
||||
#### 1.3 — Robust Futex List
|
||||
|
||||
**Kernel:** `src/syscall/futex.rs` + `src/context/context.rs`
|
||||
- Add `robust_list_head: Option<usize>` to `Context` struct
|
||||
- Implement `set_robust_list` / `get_robust_list` via proc scheme or syscall
|
||||
- On thread exit (`exit_this_context`): walk robust list, set `FUTEX_OWNER_DIED` bit, wake one waiter with `EOWNERDEAD`
|
||||
|
||||
**relibc:** `src/sync/pthread_mutex.rs`
|
||||
- Implement robust list registration in `pthread_mutex_lock`
|
||||
- Implement `pthread_mutex_consistent`: clear `EOWNERDEAD` state
|
||||
- Replace `todo_skip!` with real implementation
|
||||
|
||||
#### 1.4 — FUTEX_WAKE_OP
|
||||
|
||||
**Kernel:** `src/syscall/futex.rs`
|
||||
- Implement atomic op + wake: perform op on addr2, then wake up to `val` waiters on addr1
|
||||
- Operations: set, add, or, andn, xor, with comparison condition
|
||||
|
||||
**Impact:** glibc mutex fast path optimization. Not critical for relibc but helps ported glibc-linked binaries.
|
||||
|
||||
---
|
||||
|
||||
### Phase 2: SMP Scheduling Quality (Week 3–6)
|
||||
|
||||
**Goal:** Make multi-core actually distribute work.
|
||||
|
||||
**Depends on:** Phase 0 complete (per-CPU queues applied).
|
||||
|
||||
#### 2.1 — Work stealing (recover + fix)
|
||||
|
||||
**Kernel:** `src/context/switch.rs`
|
||||
- On `select_next_context()` empty local queue: steal from victim CPU
|
||||
- Pick victim by round-robin, steal highest-priority runnable context
|
||||
- Limit steal batch size (1–2 contexts per steal attempt)
|
||||
- Send `IpiKind::Wakeup` to target CPU if stealing woke it from idle
|
||||
|
||||
**Recovery:** P8-work-stealing needs rebase against per-CPU wiring.
|
||||
|
||||
#### 2.2 — Load balancing (recover + verify)
|
||||
|
||||
**Kernel:** `src/context/switch.rs`
|
||||
- Periodic balance trigger (every N ticks or when queue depth difference > threshold)
|
||||
- Migrate contexts from overloaded CPU to most-idle CPU
|
||||
- Respect `sched_affinity` mask during migration
|
||||
|
||||
**Recovery:** P8-load-balance is in absorbed/ — verify it's in the fork after Phase 0.
|
||||
|
||||
#### 2.3 — Reschedule IPI
|
||||
|
||||
**Kernel:** `src/arch/x86_shared/ipi.rs` + `src/context/switch.rs`
|
||||
- When waking a context on a different CPU, send `IpiKind::Switch` to that CPU
|
||||
- Currently the Switch IPI exists but is not used by the scheduler
|
||||
|
||||
#### 2.4 — Per-page TLB flush (INVLPG)
|
||||
|
||||
**Kernel:** `rmm/src/arch/x86_64.rs` + `src/context/memory.rs`
|
||||
- Add `invalidate_page(addr)` using `invlpg` instruction
|
||||
- Modify `Flusher` to track individual pages and use INVLPG when ≤ N pages affected
|
||||
- Fall back to CR3 reload only for large-scale invalidations
|
||||
|
||||
**Impact:** Every `mprotect`/`mmap`/`munmap` on a multi-threaded process currently flushes the ENTIRE TLB on every core. This is one of the most impactful single fixes.
|
||||
|
||||
#### 2.5 — TLB broadcast optimization
|
||||
|
||||
**Kernel:** `src/percpu.rs`
|
||||
- Replace per-CPU sequential `shootdown_tlb_ipi(Some(id))` loop with ICR "all excluding self" (destination shorthand 0b11)
|
||||
- Single IPI + global ack counter instead of N individual IPIs + N ack counters
|
||||
|
||||
---
|
||||
|
||||
### Phase 3: RT Scheduling (Week 4–6)
|
||||
|
||||
**Goal:** Allow applications to request real-time scheduling for latency-sensitive threads.
|
||||
|
||||
**Depends on:** Phase 0 (SchedPolicy applied) + Phase 2 (per-CPU queues).
|
||||
|
||||
#### 3.1 — Kernel RT scheduling dispatch
|
||||
|
||||
**Kernel:** `src/context/switch.rs` (from P5-sched-rt-policy — recovered in Phase 0)
|
||||
- `select_next_context()` passes:
|
||||
1. SCHED_FIFO contexts (highest RT priority first, no preemption within same prio)
|
||||
2. SCHED_RR contexts (highest RT priority first, round-robin within same prio)
|
||||
3. SCHED_OTHER contexts (existing DWRR/vruntime)
|
||||
- SCHED_RR quantum: configurable per-context (default 100ms)
|
||||
|
||||
#### 3.2 — relibc sched_* API completion
|
||||
|
||||
**relibc:** `src/header/sched/mod.rs`
|
||||
|
||||
Replace ALL `todo!()` stubs:
|
||||
|
||||
| Function | Implementation |
|
||||
|----------|---------------|
|
||||
| `sched_getscheduler(pid)` | Read policy from proc scheme attrs |
|
||||
| `sched_setscheduler(pid, policy, param)` | Write policy + RT priority via proc scheme |
|
||||
| `sched_getparam(pid, param)` | Read RT priority from proc scheme |
|
||||
| `sched_setparam(pid, param)` | Write RT priority via proc scheme |
|
||||
| `sched_get_priority_max(policy)` | Return 99 for FIFO/RR, 0 for OTHER |
|
||||
| `sched_get_priority_min(policy)` | Return 1 for FIFO/RR, 0 for OTHER |
|
||||
| `sched_rr_get_interval(pid, tp)` | Return SCHED_RR quantum (100ms default) |
|
||||
|
||||
#### 3.3 — pthread_setschedparam wiring
|
||||
|
||||
**relibc:** `src/pthread/mod.rs`
|
||||
- Replace `set_sched_param` no-op with real proc scheme call
|
||||
- Replace `set_sched_priority` no-op with real proc scheme call
|
||||
|
||||
---
|
||||
|
||||
### Phase 4: POSIX Pthread Completeness (Week 5–8)
|
||||
|
||||
**Goal:** Close remaining POSIX gaps that block application compatibility.
|
||||
|
||||
**Depends on:** Phase 0 + Phase 3 (for sched API).
|
||||
|
||||
#### 4.1 — pthread_setaffinity_np / pthread_getaffinity_np
|
||||
|
||||
**relibc:** `src/header/pthread/mod.rs` + `src/header/sched/mod.rs`
|
||||
- Implement using proc scheme "sched-affinity" write/read
|
||||
- Define `cpu_set_t` type and `CPU_SET/CPU_CLR/CPU_ZERO/CPU_ISSET` macros
|
||||
|
||||
#### 4.2 — pthread_setname_np / pthread_getname_np
|
||||
|
||||
**relibc:** `src/header/pthread/mod.rs`
|
||||
- Implement using proc scheme name write/read (kernel already supports 32-char name field)
|
||||
|
||||
#### 4.3 — pthread_cond_init CLOCK_MONOTONIC
|
||||
|
||||
**relibc:** `src/sync/cond.rs`
|
||||
- Replace `todo_skip!` with real monotonic clock support
|
||||
- Store clock choice in cond struct, use `CLOCK_MONOTONIC` for deadline calculations
|
||||
|
||||
#### 4.4 — Guard pages
|
||||
|
||||
**relibc:** `src/pthread/mod.rs`
|
||||
- In `pthread_create`, when allocating stack via mmap:
|
||||
- Map `[stack_base, stack_base + guard_size)` with `PROT_NONE`
|
||||
- Map `[stack_base + guard_size, stack_base + guard_size + stack_size)` with `PROT_READ | PROT_WRITE`
|
||||
- On thread exit, munmap both regions
|
||||
|
||||
#### 4.5 — pthread_getcpuclockid
|
||||
|
||||
**relibc:** `src/header/pthread/mod.rs`
|
||||
- Return `CLOCK_THREAD_CPUTIME_ID` (requires kernel support — add clock to `clock_gettime`)
|
||||
|
||||
**Kernel:** `src/syscall/time.rs`
|
||||
- Add `CLOCK_THREAD_CPUTIME_ID` → read `context.cpu_time`
|
||||
|
||||
#### 4.6 — PTHREAD_KEYS_MAX enforcement
|
||||
|
||||
**relibc:** `src/header/pthread/tls.rs`
|
||||
- Check `NEXTKEY` against `PTHREAD_KEYS_MAX` (1024) before allocating
|
||||
|
||||
---
|
||||
|
||||
### Phase 5: IRQ Steering and NUMA (Week 8–12)
|
||||
|
||||
**Goal:** Distribute interrupt load and respect memory locality.
|
||||
|
||||
**Depends on:** Phase 2 (per-CPU infrastructure).
|
||||
|
||||
#### 5.1 — IRQ steering
|
||||
|
||||
**Kernel:** `src/arch/x86_shared/device/ioapic.rs` + `src/arch/x86_shared/idt.rs`
|
||||
- Change I/O APIC redirection `dest` from `bsp_apic_id` to round-robin or RSS hash
|
||||
- Add per-CPU legacy IRQ handlers in IDT (not just BSP)
|
||||
- For MSI/MSI-X: set destination CPU in Message Address register
|
||||
|
||||
#### 5.2 — NUMA topology discovery
|
||||
|
||||
**Kernel:** `src/acpi/` (from P9-numa-topology — recovered in Phase 0)
|
||||
- Parse SRAT (Static Resource Affinity Table) for proximity domains
|
||||
- Parse SLIT (System Locality Distance Information Table) for inter-node distances
|
||||
- Store `NumaTopology` in kernel for O(1) scheduling lookups
|
||||
|
||||
#### 5.3 — NUMA-aware memory allocation
|
||||
|
||||
**Kernel:** `src/memory/` + frame allocator
|
||||
- Track frame NUMA node in `Frame` or `PageInfo`
|
||||
- On allocation, prefer frames from requesting CPU's NUMA node
|
||||
- Fallback to remote node when local node is exhausted
|
||||
|
||||
---
|
||||
|
||||
## 5. Dependency Chain
|
||||
|
||||
```
|
||||
Phase 0 (Patch Recovery) ← BLOCKING FOR ALL OTHERS
|
||||
│
|
||||
├──► Phase 1 (Futex Completeness)
|
||||
│ │
|
||||
│ ├──► 1.1 REQUEUE ──► condvar performance
|
||||
│ ├──► 1.2 PI ──► priority inversion fix (needs Phase 3.1)
|
||||
│ ├──► 1.3 Robust ──► deadlock prevention
|
||||
│ └──► 1.4 WAKE_OP ──► glibc compat
|
||||
│
|
||||
├──► Phase 2 (SMP Scheduling)
|
||||
│ │
|
||||
│ ├──► 2.1 Work stealing ──► core utilization
|
||||
│ ├──► 2.2 Load balancing ──► fair distribution
|
||||
│ ├──► 2.3 Reschedule IPI ──→ cross-CPU wakeup
|
||||
│ ├──► 2.4 Per-page TLB ──► mmap/mprotect performance
|
||||
│ └──► 2.5 TLB broadcast ──► IPI efficiency
|
||||
│
|
||||
├──► Phase 3 (RT Scheduling)
|
||||
│ │
|
||||
│ ├──► 3.1 Kernel RT dispatch (from Phase 0)
|
||||
│ ├──► 3.2 relibc sched_* API ──► POSIX compat
|
||||
│ └──► 3.3 pthread_setschedparam ──► app priority control
|
||||
│
|
||||
├──► Phase 4 (POSIX Pthread Completeness)
|
||||
│ │
|
||||
│ ├──► 4.1 Affinity API ──► CPU pinning
|
||||
│ ├──► 4.2 Thread naming ──► debuggability
|
||||
│ ├──► 4.3 Monotonic condvar ──► clock correctness
|
||||
│ ├──► 4.4 Guard pages ──► stack overflow detection
|
||||
│ ├──► 4.5 CPU clock ──► per-thread profiling
|
||||
│ └──► 4.6 Keys max ──► resource limit
|
||||
│
|
||||
└──► Phase 5 (IRQ + NUMA)
|
||||
│
|
||||
├──► 5.1 IRQ steering ──► interrupt distribution
|
||||
├──► 5.2 NUMA topology ──► (from Phase 0)
|
||||
└──► 5.3 NUMA allocator ──► memory locality
|
||||
```
|
||||
|
||||
**Parallel work possible:**
|
||||
- Phase 1 + Phase 2 + Phase 3 can run in parallel after Phase 0
|
||||
- Phase 4 items are independent of each other
|
||||
- Phase 5 depends on Phase 2 but not on Phase 1/3/4
|
||||
|
||||
---
|
||||
|
||||
## 6. Validation Plan
|
||||
|
||||
### 6.1 Build Evidence
|
||||
|
||||
| Check | Command |
|
||||
|-------|---------|
|
||||
| Kernel compiles | `make r.kernel` |
|
||||
| relibc compiles | `make r.relibc` |
|
||||
| Prefix rebuilt | `touch relibc kernel && make prefix` |
|
||||
| Full OS builds | `make all CONFIG_NAME=redbear-mini` |
|
||||
|
||||
### 6.2 Runtime Evidence (QEMU)
|
||||
|
||||
| Test | Verification |
|
||||
|------|-------------|
|
||||
| Multi-threaded boot | `make qemu QEMUFLAGS="-smp 4"` — all 4 CPUs active |
|
||||
| pthread smoke test | Guest: compile + run simple pthread_create/join/mutex test |
|
||||
| Work stealing | Guest: spawn 8 threads on 4-CPU QEMU, verify all CPUs utilized |
|
||||
| Futex REQUEUE | Guest: condvar broadcast benchmark — waiters wake in ≤2 batches, not N |
|
||||
| PI futex | Guest: priority inversion test — high-prio thread unblocked within 1 tick |
|
||||
| Robust mutex | Guest: kill thread holding mutex, verify EOWNERDEAD recovery |
|
||||
| RT scheduling | Guest: SCHED_FIFO thread preempts SCHED_OTHER within 100μs |
|
||||
| CPU affinity | Guest: pin thread to CPU 1, verify it never runs on CPU 0 |
|
||||
| Thread naming | Guest: `cat /scheme/proc/*/name` shows set names |
|
||||
| Guard pages | Guest: overflow stack, verify SIGSEGV (not silent corruption) |
|
||||
| TLB efficiency | Guest: mprotect benchmark — compare TLB miss rate before/after |
|
||||
|
||||
### 6.3 Validation Scripts (to create)
|
||||
|
||||
```bash
|
||||
local/scripts/test-threading-qemu.sh # Comprehensive threading smoke test
|
||||
local/scripts/test-futex-requeue-qemu.sh # REQUEUE-specific test
|
||||
local/scripts/test-futex-pi-qemu.sh # PI futex test
|
||||
local/scripts/test-futex-robust-qemu.sh # Robust mutex test
|
||||
local/scripts/test-sched-rt-qemu.sh # RT scheduling latency test
|
||||
local/scripts/test-sched-balance-qemu.sh # Load balancing on multi-vCPU
|
||||
local/scripts/test-threading-baremetal.sh # Bare metal multi-threaded stress
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Estimated Effort
|
||||
|
||||
| Phase | Duration | New Code | Recovery | Dependencies |
|
||||
|-------|----------|----------|----------|-------------|
|
||||
| Phase 0: Patch Recovery | 1–2 weeks | Minimal (rebase 5 patches) | 13 patches apply directly | None |
|
||||
| Phase 1: Futex Completeness | 2–3 weeks | REQUEUE impl + WAKE_OP | PI/robust from P8 patches | Phase 0 |
|
||||
| Phase 2: SMP Scheduling | 3–4 weeks | TLB INVLPG + broadcast opt | Work stealing from P8 | Phase 0 |
|
||||
| Phase 3: RT Scheduling | 1–2 weeks | relibc sched_* API | RT dispatch from P5 | Phase 0 |
|
||||
| Phase 4: POSIX Pthread | 2–3 weeks | Affinity/naming/guard/clock | Partial from P7 patches | Phase 0, 3 |
|
||||
| Phase 5: IRQ + NUMA | 3–4 weeks | IRQ steering + NUMA allocator | NUMA topology from P9 | Phase 0, 2 |
|
||||
|
||||
**Total:** 12–18 weeks with 1–2 developers. Phase 0 alone recovers the majority of the value in 1–2 weeks.
|
||||
|
||||
---
|
||||
|
||||
## 8. Integration with Existing Plans
|
||||
|
||||
| Plan | Relationship |
|
||||
|------|-------------|
|
||||
| `CONSOLE-TO-KDE-DESKTOP-PLAN.md` | **Consumer** — Phase 3 (KWin) needs PI futex + RT scheduling; Phase 2 (compositor) needs work stealing |
|
||||
| `IRQ-AND-LOWLEVEL-CONTROLLERS-ENHANCEMENT-PLAN.md` | **Sibling** — IRQ steering (Phase 5.1) belongs to both plans |
|
||||
| `DRM-MODERNIZATION-EXECUTION-PLAN.md` | **Consumer** — GPU worker threads benefit from load balancing + affinity |
|
||||
| `IMPLEMENTATION-MASTER-PLAN.md` | **Parent** — this plan covers the kernel threading substrate |
|
||||
| `CPU-DMA-IRQ-MSI-SCHEDULER-FIX-PLAN.md` | **Sibling** — overlaps on scheduler/IRQ delivery |
|
||||
|
||||
---
|
||||
|
||||
## 9. Bottom Line
|
||||
|
||||
The Red Bear OS threading stack is **functional for basic single-threaded and lightly-threaded
|
||||
workloads**. The SMP boot, context switching, TLB shootdown, and basic futex operations are
|
||||
correct.
|
||||
|
||||
The **critical problem** is that 6 months of threading enhancement work (P5–P9 patches) was
|
||||
lost during the local fork migration. This work exists as patch files that apply cleanly to
|
||||
the current fork — **Phase 0 (Patch Recovery) is the single highest-ROI action**.
|
||||
|
||||
After Phase 0, the remaining gaps are:
|
||||
1. **Futex REQUEUE/PI/robust** — for condvar performance and deadlock prevention
|
||||
2. **SMP work stealing + load balancing** — for multi-core utilization
|
||||
3. **RT scheduling** — for audio/compositor thread priority
|
||||
4. **POSIX pthread completeness** — for application compatibility
|
||||
5. **IRQ steering + NUMA** — for multi-socket performance
|
||||
|
||||
The **desktop-critical path** (KWin responsiveness) requires Phases 0–3. The
|
||||
**server-critical path** (multi-socket, NUMA) adds Phase 5. Phase 4 (POSIX completeness)
|
||||
benefits all paths but is not desktop-blocking.
|
||||
@@ -135,11 +135,12 @@ Two separate DMI systems exist in the source tree:
|
||||
These are **incompatible at runtime** — the acpid scheme must serve DMI data
|
||||
in *both* the flat-file and the per-field-subpath form. If acpid only
|
||||
serves one, the other system is inert. The
|
||||
[`local/sources/base/drivers/hwd/src/main.rs`](https://gitea.redbearos.org/vasilito/base)
|
||||
hwd daemon runs `acpid` and the underlying
|
||||
[`local/sources/base/drivers/acpid/src/scheme.rs`](https://gitea.redbearos.org/vasilito/base)
|
||||
`local/sources/base/drivers/hwd/src/main.rs` hwd daemon runs `acpid`
|
||||
and the underlying `local/sources/base/drivers/acpid/src/scheme.rs`
|
||||
defines the DMI surface — check what it actually serves before assuming
|
||||
both work.
|
||||
both work. (The `base` source tree lives as the `submodule/base`
|
||||
branch inside the canonical `RedBear-OS` repo per the SINGLE-REPO
|
||||
RULE in `local/AGENTS.md`.)
|
||||
|
||||
## Confirmed live TOML coverage
|
||||
|
||||
|
||||
@@ -0,0 +1,307 @@
|
||||
# Sleep Implementation Plan
|
||||
|
||||
## Status: 2026-07-01
|
||||
|
||||
| Subsystem | Status | Hardware-agnostic? |
|
||||
|-----------|--------|---------------------|
|
||||
| redbear-quirks LG Gram flags (a) | ✅ Committed (4d270bab2), pushed | Yes |
|
||||
| acpid AML S-state sequence (b) | ✅ Committed (5d2d114), built | Yes |
|
||||
| Kernel kstop s2idle/S3 handler (c) | ✅ Committed (75c7618), built | Yes |
|
||||
| Phase J: libredox fork + syscall EnterS2Idle/ExitS2Idle | ✅ Committed (aadf55b base, 6b98c64 kernel), built | Yes |
|
||||
| Phase II: S3 entry path (PM1 register write) | ✅ Committed (9f6a428 kernel), built | Yes |
|
||||
| Phase II.X: S3 resume trampoline (64-bit assembly) | ✅ Committed (1be659b, 9bc1fbf kernel), built | Yes |
|
||||
| Phase II.X.W: FACS parser + SetS3WakingVector/EnterS3 AcPiVerbs | ✅ Committed (b0f4fee syscall, 475f96e/9bc1fbf kernel, dcd70a1 base), built | Yes |
|
||||
| Broad OEM DMI (Dell/HP/Lenovo) | ✅ Committed (4d270bab2 quirks), built | Yes |
|
||||
| redbear-mini ISO build | ✅ Succeeds, 512 MB | — |
|
||||
| QEMU boot test | ✅ Passes, reaches Red Bear login | — |
|
||||
| Build system patch verification (`make verify-patches`) | ✅ Added (1834c3bf Makefile, 32403ccf4 script) | — |
|
||||
| Phase K: convert local sources to git submodules | ⏳ Deferred — requires gitea mirror per source | — |
|
||||
|
||||
## Phase J Architecture (Current)
|
||||
|
||||
The s2idle / s3 coordination path uses **two parallel APIs**:
|
||||
|
||||
1. **kstop string-arg path** (Phase I.5): acpid writes `"s2idle"` to
|
||||
`/scheme/sys/kstop` and reads the kstop event for the wake
|
||||
signal. This is the original path; it works without the
|
||||
AcpiVerb extension.
|
||||
2. **Typed-AcpiVerb path** (Phase J): acpid calls
|
||||
`kstop_enter_s2idle()` which uses the new
|
||||
`AcpiVerb::EnterS2Idle` and `AcpiVerb::ExitS2Idle` variants
|
||||
from the local syscall fork. This is the preferred path now
|
||||
that Phase J's libredox fork is in place.
|
||||
|
||||
Both paths are fully wired and work. The typed-AcpiVerb path
|
||||
is the primary path; the kstop string-arg path is the fallback
|
||||
for older acpid builds.
|
||||
|
||||
### Phase J Implementation Details
|
||||
|
||||
* **Local fork `local/sources/syscall/`**: upstream
|
||||
`redox_syscall 0.8.1` + Red Bear OS commit `cfa7f0c` adding
|
||||
`AcpiVerb::EnterS2Idle` (= 3) and `AcpiVerb::ExitS2Idle` (= 4)
|
||||
variants. The version field stays at upstream 0.8.1 per the
|
||||
AGENTS.md "GOLDEN RULE".
|
||||
* **Local fork `local/sources/libredox/`**: upstream
|
||||
`libredox 0.1.17` with the `redox_syscall` dep redirected
|
||||
to `path = "../syscall"`. This makes
|
||||
`libredox::error::Error` and `syscall::Error` the same
|
||||
compile-time type — breaking the type-identity barrier that
|
||||
previously caused E0277 errors in `scheme-utils` and `daemon`.
|
||||
* **Base `Cargo.toml`**: `[patch.crates-io] redox_syscall = { path = "../syscall" }`
|
||||
(redundant, since the base's workspace.dependencies already
|
||||
uses the local path) and `[patch.crates-io] libredox = { path = "../libredox" }`.
|
||||
* **Kernel `Cargo.toml`**: `[workspace] members = [".", "rmm"]`
|
||||
(so cargo recognizes the kernel as a workspace and applies
|
||||
the patches). `[patch."https://gitlab.redox-os.org/redox-os/syscall.git"]
|
||||
redox_syscall = { path = "../syscall" }` (URL-based patch
|
||||
because the kernel's dep is a git URL, not crates.io).
|
||||
`[patch.crates-io] libredox = { path = "../libredox" }`.
|
||||
* **Patch file**: `local/patches/syscall/P1-acpiverb-enter-exit-s2idle.patch`
|
||||
is the durable overlay patch backing the syscall fork commit.
|
||||
|
||||
### Phase J End-to-End s2idle Flow
|
||||
|
||||
1. acpid: `enter_s2idle()` (`_TTS(0)`, `_PTS(0)`, `_SST(3)`)
|
||||
2. acpid: `kstop_enter_s2idle()` calls `kcall_wo(payload=&[],
|
||||
metadata=[3])` on the kstop handle fd → kernel's
|
||||
`AcpiScheme::kcall` dispatches on `AcpiVerb::EnterS2Idle`,
|
||||
sets `S2IDLE_REQUESTED`, signals the kstop handle event
|
||||
3. kernel idle path: `mwait_loop()` at deepest C-state
|
||||
4. SCI breaks MWAIT
|
||||
5. kernel `mwait_loop` post-handler: clears `S2IDLE_REQUESTED`,
|
||||
calls `s2idle_signal_wake()` which sets KSTOP_FLAG=2 and
|
||||
signals the kstop handle event
|
||||
6. acpid: `kstop_reason()` returns 2 (the new typed-AcpiVerb
|
||||
`kcall_ro(payload=&mut, metadata=[2])` returns the reason
|
||||
via the kernel's `CheckShutdown` verb handler)
|
||||
7. acpid: `exit_s2idle()` (`_SST(2)`, `_WAK(0)`, `_SST(1)`)
|
||||
8. loop
|
||||
|
||||
### Phase J Test Plan
|
||||
|
||||
* **Build verification**: `redbear-mini.iso` (512 MB) builds
|
||||
successfully with the Phase J commits. The build system
|
||||
applies the patches in the right order.
|
||||
* **QEMU verification**: boot the ISO in QEMU. The cpufreqd
|
||||
daemon should NOT oscillate (Phase H fix). The acpid
|
||||
main loop should NOT log repeated `P0→P1` transitions.
|
||||
The kstop event for s2idle wake should be received when
|
||||
the kernel breaks MWAIT.
|
||||
* **Patch application verification**: run `cargo metadata
|
||||
--format-version 1` and confirm the resolved source URL
|
||||
for `redox_syscall` and `libredredox` is the local fork path.
|
||||
|
||||
## Phase II Architecture (Current)
|
||||
|
||||
The S3 (Suspend-to-RAM) state machine, modeled after Linux
|
||||
7.1's `arch/x86/kernel/acpi/wakeup_64.S` and
|
||||
`arch/x86/kernel/acpi/sleep.c`:
|
||||
|
||||
1. **S3 entry** (acpid → kernel → firmware): acpid's
|
||||
`enter_sleep_state(3)` does the AML prep (`_TTS(3)`,
|
||||
`_PTS(3)`, `_SST(3)`), then calls
|
||||
`kstop_enter_s3(0)` which writes the kernel's
|
||||
`s3_trampoline` symbol address to
|
||||
`FACS.xfirmware_waking_vector` via the new
|
||||
`SetS3WakingVector` AcPiVerb. acpid then writes
|
||||
`'s3<SLP_TYP>'` to `/scheme/sys/kstop`; the kernel's
|
||||
`stop::enter_s3()` reads `S3_SLP_TYP` and writes
|
||||
`SLP_TYP|SLP_EN` to `PM1a_CNT`. The platform
|
||||
firmware enters S3.
|
||||
2. **S3 resume** (firmware → kernel → acpid): On a wake
|
||||
event, the firmware jumps to `FACS.waking_vector`
|
||||
(the s3_trampoline). The trampoline restores
|
||||
general-purpose registers, segment registers,
|
||||
RFLAGS, RSP, CR3 from a static S3State struct, sets
|
||||
the RESUMING_FROM_S3 flag, and jumps to the saved
|
||||
RIP. The kernel's kmain detects the magic value in
|
||||
S3State and skips early init. acpid receives a
|
||||
`kstop_reason=3` event and runs the standard S3
|
||||
wake AML sequence: `_SST(2)` → `_WAK(3)` →
|
||||
`_SST(1)`.
|
||||
|
||||
The S3 state save in `kernel/src/arch/x86_shared/stop.rs`
|
||||
and the resume trampoline in
|
||||
`kernel/src/arch/x86_shared/s3_resume.rs` are both
|
||||
present and built.
|
||||
|
||||
Hardware-agnostic: works on any x86_64 system with
|
||||
standard ACPI S3 support (Dell, HP, Lenovo, LG Gram 14).
|
||||
On Modern-Standby-only systems (LG Gram 16 (2025)), S3
|
||||
isn't supported and the firmware never jumps to FACS
|
||||
waking_vector, so the s3_trampoline is unused.
|
||||
|
||||
## Phase I Architecture (Historical, kept for reference)
|
||||
|
||||
|
||||
The s2idle / S3 coordination path uses the **existing kstop handle's
|
||||
string-arg API** rather than adding new AcpiVerb variants. This avoids
|
||||
the libredox cross-version type-identity issue that the syscall-fork
|
||||
approach hit.
|
||||
|
||||
### Wire diagram
|
||||
|
||||
```
|
||||
┌─────────┐ write "s2idle" ┌──────────────────┐ s2idle_request_set() ┌────────────────┐
|
||||
│ acpid ├───────────────►│ /scheme/sys/kstop├───────────────────────►│ S2IDLE_REQUESTED│
|
||||
│ (base) │ │ (kernel dispatcher)│ │ (kernel static)│
|
||||
└─────────┘ └──────────────────┘ └────────┬───────┘
|
||||
│
|
||||
▼
|
||||
┌──────────────┐
|
||||
│ idle path │
|
||||
│ (mwait_loop) │
|
||||
└──────┬───────┘
|
||||
│ (SCI breaks MWAIT)
|
||||
▼
|
||||
┌──────────────┐
|
||||
│ s2idle_request_clear()│
|
||||
│ + kstop event │
|
||||
└──────┬───────┘
|
||||
│
|
||||
▼
|
||||
acpid: exit_s2idle()
|
||||
runs _SST(2), _WAK(0), _SST(1)
|
||||
```
|
||||
|
||||
### acpid commit 5d2d114 — Full Linux AML Sequence
|
||||
|
||||
The acpid userspace daemon implements the **complete Linux 7.1 ACPI
|
||||
sleep state machine** on top of the existing AML interpreter. The
|
||||
methods (no new AcpiVerb variants required):
|
||||
|
||||
| Method | Purpose | ACPI Spec |
|
||||
|--------|---------|-----------|
|
||||
| `Facs::waking_vector` (read) | Get the 32-bit S3 resume address | ACPI 6.5 §5.2.10 |
|
||||
| `Facs::set_waking_vector` (new) | Write the 32-bit S3 resume address | ACPI 6.5 §5.2.10 |
|
||||
| `Facs::set_x_waking_vector` (new) | Write the 64-bit S3 resume address | ACPI 6.5 §5.2.10 |
|
||||
| `set_system_status_indicator` (new) | Call `\_SI._SST(n)` | ACPI 6.5 §6.5.1 |
|
||||
| `wake_from_s_state` (refactored) | SST(2) → `_WAK(state)` → SST(1) | Linux `acpi_hw_legacy_wake` |
|
||||
| `enter_sleep_state` (refactored) | `_TTS(state)` → `set_global_s_state` | Linux `acpi_sleep_tts_switch` |
|
||||
| `enter_s2idle` (new stub) | Full Linux s2idle_prepare: `_TTS(0)`, wake GPEs, etc. | Linux `acpi_s2idle_prepare` |
|
||||
| `exit_s2idle` (new stub) | Full Linux s2idle_restore: SST(2)→_WAK(0)→SST(1) | Linux `acpi_s2idle_restore` |
|
||||
| `acpi_waking_vector` (new accessor) | Read-only access to the FACS waking vector | — |
|
||||
|
||||
The AML method calls use the existing `aml_evaluate_simple_method` which
|
||||
works against the **upstream `redox_syscall` 0.8.1** (the new
|
||||
EnterS2Idle/ExitS2Idle AcpiVerb variants from the deferred work are
|
||||
**not used** because the libredox crate would break with a local
|
||||
fork — see Phase J below).
|
||||
|
||||
### Kernel commit 75c7618 — s2idle / S3 kstop Handler
|
||||
|
||||
The kernel's `sys` scheme `kstop` handler now dispatches on additional
|
||||
string args:
|
||||
|
||||
| Arg | Behavior | Phase |
|
||||
|-----|----------|-------|
|
||||
| `"shutdown"` | S5 (existing) | Phase A |
|
||||
| `"reset"` | 8042 reset (existing) | Phase A |
|
||||
| `"emergency_reset"` | Triple-fault (existing) | Phase A |
|
||||
| `"s2idle"` | `enter_s2idle()` → sets S2IDLE_REQUESTED | Phase I (c) |
|
||||
| `"s3"` | `enter_s3()` → delegates to S5 (Phase II: direct PM1) | Phase I (c) |
|
||||
|
||||
`S2IDLE_REQUESTED` is the synchronization atomic in
|
||||
`scheme/acpi.rs` that the kernel's idle path polls before calling
|
||||
`mwait_loop()`. It's `AtomicBool` with explicit `Acquire`/`Release`
|
||||
ordering. Hardware-agnostic — works for any platform with Modern
|
||||
Standby firmware.
|
||||
|
||||
### Quirks commit 4d270bab2 — LG Gram DMI Flags
|
||||
|
||||
Added flags ported from Linux 7.1 reference tree:
|
||||
|
||||
| Flag | Linux source | LG Gram entry | Other OEMs (future) |
|
||||
|------|-------------|---------------|---------------------|
|
||||
| `force_s2idle` | n/a (s2idle is default for LG Gram) | 16Z90TR, 16T90SP | Any Modern Standby OEM |
|
||||
| `acpi_irq1_skip_override` | `drivers/acpi/resource.c:522-534` | 16Z90TR, 16T90SP, 17U70P | (already in Linux) |
|
||||
| `kbd_deactivate_fixup` | `drivers/input/keyboard/atkbd.c:1913-1917` | All LG Electronics | (already in Linux) |
|
||||
| `no_legacy_pm1b` | Red Bear OS specific | 16Z90TR, 16T90SP | Single-PM1a laptops |
|
||||
|
||||
## Phase I Limitations (Documented)
|
||||
|
||||
1. **S3 resume trampoline is not implemented.** `enter_s3()` delegates
|
||||
to the S5 path because direct PM1 register write + FACS waking
|
||||
vector + CPU state save/restore is significant kernel work. Phase II.
|
||||
|
||||
2. **s2idle wake interrupt handler is not implemented.** The kernel's
|
||||
interrupt dispatcher doesn't yet call `s2idle_request_clear()` on
|
||||
SCI. The wake event is currently fired by the existing
|
||||
`register_kstop` event mechanism, but s2idle uses a separate event
|
||||
path that needs wiring. Phase I.5.
|
||||
|
||||
3. **acpid's `enter_s2idle` / `exit_s2idle` are stubs.** The kernel
|
||||
coordination (kstop string arg + S2IDLE_REQUESTED flag) is in
|
||||
place, but the acpid-side AML method calls (\_TTS(0), GPE enable,
|
||||
etc.) are not yet wired to the kstop event flow. acpid's main
|
||||
event loop only handles the existing kstop shutdown path. Phase
|
||||
I.5.
|
||||
|
||||
4. **The EnterS2Idle/ExitS2Idle AcPiVerb extension is deferred to
|
||||
Phase J.** See next section.
|
||||
|
||||
## Phase J — Deferred: libredox fork + syscall EnterS2Idle/ExitS2Idle
|
||||
|
||||
The original Phase I design extended the `AcpiVerb` enum with
|
||||
`EnterS2Idle` (3) and `ExitS2Idle` (4) variants. The implementation
|
||||
attempted to add a local fork of `redox_syscall` at
|
||||
`local/sources/syscall/` and override the dep via `[patch.crates-io]`
|
||||
in the base/kernel `Cargo.toml`.
|
||||
|
||||
**Blocker discovered:** `libredox = "0.1.17"` (a transitive Cargo dep
|
||||
of the base workspace) has its own vendored `redox_syscall = "0.8"`
|
||||
dep. The `[patch.crates-io]` in the base workspace's `Cargo.toml`
|
||||
only applies to direct deps, not to deps of deps. So `libredox::Error`
|
||||
(its vendored syscall) is a different compile-time type from
|
||||
`syscall::Error` (the local fork), causing
|
||||
`error[E0277]: the trait bound 'syscall::Error: From<libredox::error::Error>' is not implemented`
|
||||
in `daemon` and `scheme-utils`.
|
||||
|
||||
**Workaround (Phase I current):** Don't add new AcPiVerb variants. Use
|
||||
the existing kstop handle's string-arg API. This works without any
|
||||
cross-version type issues.
|
||||
|
||||
**Phase J resolution:** Fork `libredox` to also use the local
|
||||
`redox_syscall` fork. Steps:
|
||||
1. Create `local/sources/libredox/` as a fork of `crates.io/libredox 0.1.17`.
|
||||
2. Update its `Cargo.toml` to use the local `redox_syscall`.
|
||||
3. The base/kernel `Cargo.toml` will then need a `[patch.crates-io]
|
||||
libredox = { path = "local/sources/libredox" }` override.
|
||||
4. Now the syscall extension works end-to-end.
|
||||
|
||||
**Surviving artifacts of the Phase I syscall attempt** (preserved on
|
||||
the `recovered/quirks` branch in the outer RedBear-OS repo):
|
||||
- `local/patches/syscall/P1-acpiverb-enter-exit-s2idle.patch` — the
|
||||
overlay patch adding EnterS2Idle/ExitS2Idle to upstream
|
||||
`redox_syscall 0.8.1`. The patch is verified to apply cleanly
|
||||
against fresh upstream.
|
||||
- Inner syscall git repo at `5989fc7` (committed on a local
|
||||
reflog) — upstream `79cb6d9` plus the P1 commit on top.
|
||||
- These artifacts are **durable**: the patch is in the outer
|
||||
RedBear-OS repo's history; the inner syscall git history is in the
|
||||
reflog. Phase J picks up from here.
|
||||
|
||||
## Cross-references
|
||||
|
||||
- **Linux 7.1 reference tree** at
|
||||
`/mnt/data/Builds/RedBear-OS/local/reference/linux-7.1/`:
|
||||
- `drivers/acpi/sleep.c:735` — `acpi_s2idle_prepare`
|
||||
- `drivers/acpi/sleep.c:758` — `acpi_s2idle_wake`
|
||||
- `drivers/acpi/sleep.c:821` — `acpi_s2idle_restore`
|
||||
- `drivers/acpi/acpica/hwsleep.c:81-127` — `acpi_hw_legacy_sleep`
|
||||
- `drivers/acpi/acpica/hwsleep.c:255-314` — `acpi_hw_legacy_wake`
|
||||
- `kernel/power/suspend.c:91` — `s2idle_enter`
|
||||
- `kernel/power/suspend.c:133` — `s2idle_wake`
|
||||
- `arch/x86/kernel/acpi/sleep.c:38` — `acpi_get_wakeup_address`
|
||||
|
||||
- **Red Bear OS outer** commits on `0.2.4`:
|
||||
- `4d270bab2` — redbear-quirks LG Gram DMI flags
|
||||
- `4191b8543` — base submodule pointer (acpid AML sequence)
|
||||
- `850124559` — kernel submodule pointer (s2idle kstop handler)
|
||||
|
||||
- **Red Bear OS inner** commits (historical — these repos have since been
|
||||
merged as `submodule/base` and `submodule/kernel` branches inside the
|
||||
canonical `RedBear-OS` repo per the SINGLE-REPO RULE):
|
||||
- `redbear-os-base 5d2d114` — acpid: full Linux AML S-state sequence
|
||||
- `redbear-os-kernel 75c7618` — kernel: s2idle / s3 kstop handler
|
||||
Submodule local/recipes/archives/uutils-tar/source deleted from e4c2affa98
@@ -1,6 +1,5 @@
|
||||
[source]
|
||||
tar = "https://github.com/westes/flex/releases/download/v2.6.4/flex-2.6.4.tar.gz"
|
||||
blake3 = "d78b714ac38bd9de7f9b44a078efed82e96ed43e7cf9cd33944a7f379a2d09a4"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
[source]
|
||||
tar = "https://ftp.gnu.org/gnu/m4/m4-1.4.21.tar.xz"
|
||||
blake3 = "a23e9503084fa4087f45bb7bb9c39f0cf8e0f046e0f94e55c40a8da124c1fd68"
|
||||
tar = "https://ftp.gnu.org/gnu/m4/m4-1.14.21.tar.xz"
|
||||
patches = ["redox.patch"]
|
||||
|
||||
[build]
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
[source]
|
||||
tar = "https://github.com/mesonbuild/meson/releases/download/1.3.0/meson-1.3.0.tar.gz"
|
||||
blake3 = "c73a725a996ca1b7ee74b2f7b0af666d088c0538309af462f4b3745fb2f41047"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
|
||||
Submodule local/recipes/dev/ninja-build/source deleted from d829f42b8d
@@ -7,7 +7,6 @@
|
||||
# build independently with just qtbase + KF6 deps.
|
||||
[source]
|
||||
tar = "https://invent.kde.org/plasma/breeze/-/archive/v6.3.4/breeze-v6.3.4.tar.gz"
|
||||
blake3 = "ac311365edb6540c06ec6923e0c44accfe204beaa4d0630bf8f398982eb01d89"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
# kdesu is not built (needs sudo or kdesu backend which doesn't exist on Redox).
|
||||
[source]
|
||||
tar = "https://invent.kde.org/plasma/kde-cli-tools/-/archive/v6.3.4/kde-cli-tools-v6.3.4.tar.gz"
|
||||
blake3 = "65b55bfdea0ba55a2dc78480ded5a2e2230d0d3ab00194de9610677c91ede1c6"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#TODO: KDecoration3 — window decoration library. Required by KWin.
|
||||
[source]
|
||||
tar = "https://invent.kde.org/plasma/kdecoration/-/archive/v6.3.4/kdecoration-v6.3.4.tar.gz"
|
||||
blake3 = "43ce6200f914e72c27dfa547f3a50859a42e0e13eb0756e8e68af912bbbfbda5"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
# QML, tests, and examples disabled.
|
||||
[source]
|
||||
tar = "https://invent.kde.org/frameworks/attica/-/archive/v6.10.0/attica-v6.10.0.tar.gz"
|
||||
blake3 = "0b4d10aca536ffc4c2a81d6d99f2ea7f88f36490c0d9aa45041cd4db1c3304ad"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
|
||||
@@ -31,4 +31,3 @@ cmake --install . --prefix "${COOKBOOK_STAGE}/usr"
|
||||
|
||||
[source]
|
||||
tar = "https://invent.kde.org/frameworks/extra-cmake-modules/-/archive/v6.11.0/extra-cmake-modules-v6.11.0.tar.gz"
|
||||
blake3 = "463d88e8878b75284fee9ab83480fab0142558c566d1987a58b95814e3ad9ff2"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#TODO: KArchive — archive reading/writing framework. Depends on qtbase, qtdeclarative, kf6-extra-cmake-modules.
|
||||
[source]
|
||||
tar = "https://invent.kde.org/frameworks/karchive/-/archive/v6.10.0/karchive-v6.10.0.tar.gz"
|
||||
blake3 = "691eb190c1f4089af9a3d7b2f808f217ce3ecbfbff8854f679551b0bff65873e"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#TODO: KAuth — policykit-like authorization framework. Depends on qtbase, kf6-kcoreaddons. Still using FAKE backend until PolkitQt6-1 is packaged.
|
||||
[source]
|
||||
tar = "https://invent.kde.org/frameworks/kauth/-/archive/v6.10.0/kauth-v6.10.0.tar.gz"
|
||||
blake3 = "486be662cbc317d59d3eae0a7bb4f98357d96e9651b809fb284cbdb7fe58b75c"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#TODO: KBookmarks — bookmark management framework.
|
||||
[source]
|
||||
tar = "https://invent.kde.org/frameworks/kbookmarks/-/archive/v6.10.0/kbookmarks-v6.10.0.tar.gz"
|
||||
blake3 = "bb8bad9cbfadb951b9162cd94f3ea0f40cd31c564f66fd607cdc392c615f74f3"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#TODO: KCMUtils — System Settings control modules. Depends on kf6-kio, kf6-kdeclarative.
|
||||
[source]
|
||||
tar = "https://invent.kde.org/frameworks/kcmutils/-/archive/v6.10.0/kcmutils-v6.10.0.tar.gz"
|
||||
blake3 = "9d64a3d8c68ca8093b3da5715fe6bcb01090bca98c65263300d852ce4bc7b66d"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#TODO: KCodecs — charset and encoding utilities. Depends on qtbase, kf6-extra-cmake-modules, kf6-ki18n.
|
||||
[source]
|
||||
tar = "https://invent.kde.org/frameworks/kcodecs/-/archive/v6.10.0/kcodecs-v6.10.0.tar.gz"
|
||||
blake3 = "bad247cd4c94dd17b66889ee65cb50be7a5c6c9c8b0ecc3dad16a9f888a6b346"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#TODO: KColorScheme — color scheme management. Depends on qtbase, kf6-kconfig, kf6-kcoreaddons, kf6-ki18n, kf6-kguiaddons.
|
||||
[source]
|
||||
tar = "https://invent.kde.org/frameworks/kcolorscheme/-/archive/v6.10.0/kcolorscheme-v6.10.0.tar.gz"
|
||||
blake3 = "c7726ef35373842111812885cc6dbead8866be215b7615a4196ffa4d117502c7"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#TODO: KCompletion — auto-completion widgets and utilities
|
||||
[source]
|
||||
tar = "https://invent.kde.org/frameworks/kcompletion/-/archive/v6.10.0/kcompletion-v6.10.0.tar.gz"
|
||||
blake3 = "9a8d137c3a66461c983d534273fd72f4a0923c2e1ba406124d824f44a408dfec"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#TODO: KDE KConfig — configuration framework, no GUI deps. Depends on qtbase, qtdeclarative, kf6-extra-cmake-modules.
|
||||
[source]
|
||||
tar = "https://invent.kde.org/frameworks/kconfig/-/archive/v6.10.0/kconfig-v6.10.0.tar.gz"
|
||||
blake3 = "e7f44313e7af866493429bbdda223163c8bb5d262a778013f6b7d44866eb94ad"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#TODO: KConfigWidgets — configuration widgets, KConfigXT. Depends on qtbase, kf6-kconfig, kf6-kcoreaddons, kf6-ki18n, kf6-kwidgetsaddons, kf6-kcodecs, kf6-kauth, kf6-kguiaddons, kf6-kcolorscheme.
|
||||
[source]
|
||||
tar = "https://invent.kde.org/frameworks/kconfigwidgets/-/archive/v6.10.0/kconfigwidgets-v6.10.0.tar.gz"
|
||||
blake3 = "a69b1dfa8e1cdda4b66747eb5dbdc3a9c18a7000e4e82d051efa02453f364920"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
|
||||
@@ -47,4 +47,3 @@ done
|
||||
|
||||
[source]
|
||||
tar = "https://invent.kde.org/frameworks/kcoreaddons/-/archive/v6.10.0/kcoreaddons-v6.10.0.tar.gz"
|
||||
blake3 = "d29044727564b353a53152b3ede5e103e4212f1e918fb2a90295233ab8c12610"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#TODO: KCrash — crash handler, backtrace generation. OpenGL deps disabled for software rendering.
|
||||
[source]
|
||||
tar = "https://invent.kde.org/frameworks/kcrash/-/archive/v6.10.0/kcrash-v6.10.0.tar.gz"
|
||||
blake3 = "7be046924fb7d8da5a430e29ce23bd4cef764f1ad3480c6b1fa302f84383f266"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#TODO: KDBusAddons — D-Bus convenience wrappers. Needs Qt6DBus (qtbase with FEATURE_dbus=ON).
|
||||
[source]
|
||||
tar = "https://invent.kde.org/frameworks/kdbusaddons/-/archive/v6.10.0/kdbusaddons-v6.10.0.tar.gz"
|
||||
blake3 = "da8a2fbeddc08eae88fdce837657c27b848016436c9c51ac7f83712573b04363"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
# QML-backed runtime pieces stay disabled with BUILD_WITH_QML=OFF.
|
||||
[source]
|
||||
tar = "https://invent.kde.org/frameworks/kdeclarative/-/archive/v6.10.0/kdeclarative-v6.10.0.tar.gz"
|
||||
blake3 = "a83aebc43e0e516c284c62dfd2b42a8605ddfd250d4c0aa8fb394315fdf7d277"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
[source]
|
||||
tar = "https://invent.kde.org/frameworks/kded/-/archive/v6.10.0/kded-v6.10.0.tar.gz"
|
||||
blake3 = "ca15e7e765cc2657953816e74a059d472b8be192100f7bcdbd213a7533d0554d"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#TODO: KGlobalAccel — global keyboard shortcuts. Needs kf6-kcrash + kf6-kdbusaddons.
|
||||
[source]
|
||||
tar = "https://invent.kde.org/frameworks/kglobalaccel/-/archive/v6.10.0/kglobalaccel-v6.10.0.tar.gz"
|
||||
blake3 = "72f82c80f17bef8245062f24d3e5f48c692048e99ac968b064716546c66ff0cb"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#TODO: KGuiAddons — GUI utilities, color management, text selection. Depends on qtbase, kf6-extra-cmake-modules. Wayland/X11 disabled.
|
||||
[source]
|
||||
tar = "https://invent.kde.org/frameworks/kguiaddons/-/archive/v6.10.0/kguiaddons-v6.10.0.tar.gz"
|
||||
blake3 = "ec8e69a509e89b639f8d090e4f8dd20c6a9dbb4153e18b6d896ee53e2260e894"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#TODO: KI18n — internationalization framework, gettext integration. Depends on qtbase, qtdeclarative, kf6-extra-cmake-modules.
|
||||
[source]
|
||||
tar = "https://invent.kde.org/frameworks/ki18n/-/archive/v6.10.0/ki18n-v6.10.0.tar.gz"
|
||||
blake3 = "1b76daa1b96fa211b9ff8289a6f82a16cde26dcb6948e2cc6400989845581ffa"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#TODO: KIconThemes — icon theme management. Needs kf6-karchive for icon loading.
|
||||
[source]
|
||||
tar = "https://invent.kde.org/frameworks/kiconthemes/-/archive/v6.10.0/kiconthemes-v6.10.0.tar.gz"
|
||||
blake3 = "9794899fc57e98dae244aa11afc4bf7090e6b81c127b888d1c999dcc974fde58"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#TODO: KIdleTime — idle time detection. Used by KWin for screen dimming/locking.
|
||||
[source]
|
||||
tar = "https://invent.kde.org/frameworks/kidletime/-/archive/v6.10.0/kidletime-v6.10.0.tar.gz"
|
||||
blake3 = "b88bb3c687aa6620b796d13fe9d31bb623e87a50c7613ee61d7d5a5a4ff87e0c"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#TODO: KItemModels — Qt model framework extensions (KDescendantsProxyModel, KConcatenateRowsProxyModel, etc.)
|
||||
[source]
|
||||
tar = "https://invent.kde.org/frameworks/kitemmodels/-/archive/v6.10.0/kitemmodels-v6.10.0.tar.gz"
|
||||
blake3 = "0ddb72039a68bcfa4774f6909aa07bf7c765482b287e77446d81810e0cafaa3f"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#TODO: KItemViews — item view widgets (list/tree/table views)
|
||||
[source]
|
||||
tar = "https://invent.kde.org/frameworks/kitemviews/-/archive/v6.10.0/kitemviews-v6.10.0.tar.gz"
|
||||
blake3 = "5209aa93e4091b579044f38d5adadc04f07a04c426d554606549827289eba347"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
|
||||
@@ -28,76 +28,6 @@ include(CMakePackageConfigHelpers)
|
||||
set(REQUIRED_QT_VERSION 6.6.0)
|
||||
find_package(Qt6 ${REQUIRED_QT_VERSION} CONFIG REQUIRED Widgets)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
|
||||
set(EXCLUDE_DEPRECATED_BEFORE_AND_AT 0 CACHE STRING "Control the range of deprecated API excluded from the build [default=0].")
|
||||
|
||||
@@ -113,7 +43,6 @@ ecm_setup_version(PROJECT VARIABLE_PREFIX KITEMVIEWS
|
||||
PACKAGE_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/KF6ItemViewsConfigVersion.cmake"
|
||||
SOVERSION 6)
|
||||
|
||||
|
||||
#ecm_install_po_files_as_qm(poqm)
|
||||
|
||||
ecm_set_disabled_deprecation_versions(
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#TODO: KJobWidgets — job and progress tracking widgets. Depends on qtbase, kf6-kcoreaddons, kf6-ki18n, kf6-kwidgetsaddons. DBus/X11 disabled.
|
||||
[source]
|
||||
tar = "https://invent.kde.org/frameworks/kjobwidgets/-/archive/v6.10.0/kjobwidgets-v6.10.0.tar.gz"
|
||||
blake3 = "686a65fdd7cb4ff7e8452f017360b4bb1c3e10be399312da31011d8b9f87175e"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#TODO: KNewStuff — core-only build on Redox. Qt Quick, widgets, tools, and Kirigami-facing surfaces disabled. KF6Attica now available in-tree (kf6-attica recipe).
|
||||
[source]
|
||||
tar = "https://invent.kde.org/frameworks/knewstuff/-/archive/v6.10.0/knewstuff-v6.10.0.tar.gz"
|
||||
blake3 = "ddbb41f89c16471664012f3bcadb5b9bef709b561737a6b12d8ae3186a7012df"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#TODO: KNotifications — notification framework. Depends on qtbase, kf6-kconfig, kf6-kcoreaddons, kf6-ki18n, kf6-kwindowsystem. D-Bus enabled (redbear-notifications provides org.freedesktop.Notifications).
|
||||
[source]
|
||||
tar = "https://invent.kde.org/frameworks/knotifications/-/archive/v6.10.0/knotifications-v6.10.0.tar.gz"
|
||||
blake3 = "eab13e1471040245b6f372fb0e4d0bc73397ad36017174b584c9561f93783e99"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#TODO: KPackage — package framework, theme/plugin/installer management. Needs kf6-kservice.
|
||||
[source]
|
||||
tar = "https://invent.kde.org/frameworks/kpackage/-/archive/v6.10.0/kpackage-v6.10.0.tar.gz"
|
||||
blake3 = "243a95a03aefe064719138893fb32442454af1d6a3e0b34c3d5de0bd5ef8c6c1"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#TODO: KService — service and plugin framework, .desktop file parsing. Needs kf6-kdbusaddons.
|
||||
[source]
|
||||
tar = "https://invent.kde.org/frameworks/kservice/-/archive/v6.10.0/kservice-v6.10.0.tar.gz"
|
||||
blake3 = "d41008009677a0a9d00dc76ab8a0956276397559d1d39eb7b249e3054b422ebe"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#TODO: KTextWidgets — text editing widgets. Depends on kf6-sonnet for spell-check integration.
|
||||
[source]
|
||||
tar = "https://invent.kde.org/frameworks/ktextwidgets/-/archive/v6.10.0/ktextwidgets-v6.10.0.tar.gz"
|
||||
blake3 = "06c0b453c6ce3742a626af3f942a8045987f87d9b97e5c407e6383bb69d37947"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#TODO: KWallet — build the real KF6 client library on Redox; kwalletd, kwallet-query, translations, and X11 runtime paths stay disabled until the broader runtime service surface is proven.
|
||||
[source]
|
||||
tar = "https://invent.kde.org/frameworks/kwallet/-/archive/v6.10.0/kwallet-v6.10.0.tar.gz"
|
||||
blake3 = "1a6b37789fa1f0dddd459c64b93ee3c6ab5d39a041aedff00805393948164659"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#TODO: KWayland — Qt/C++ wrapper for Wayland protocols. Required by KWin.
|
||||
[source]
|
||||
tar = "https://download.kde.org/stable/plasma/6.3.4/kwayland-6.3.4.tar.xz"
|
||||
blake3 = "453454338a15da06fea7c15cbb38c82aa63c9d0f91490573c6f24d8bcbc98dd3"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
|
||||
@@ -47,55 +47,6 @@ find_package(Qt6WaylandClient ${QT_MIN_VERSION} CONFIG REQUIRED NO_MODULE COMPON
|
||||
|
||||
find_package(Wayland 1.15 COMPONENTS Client)
|
||||
find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
set_package_properties(Wayland PROPERTIES
|
||||
TYPE REQUIRED
|
||||
)
|
||||
@@ -166,7 +117,6 @@ install(FILES "${CMAKE_CURRENT_BINARY_DIR}/KWaylandConfig.cmake"
|
||||
|
||||
install(EXPORT KWaylandTargets DESTINATION "${CMAKECONFIG_INSTALL_DIR}" FILE KWaylandTargets.cmake NAMESPACE Plasma::)
|
||||
|
||||
|
||||
install(FILES ${kwayland_version_header}
|
||||
DESTINATION ${KDE_INSTALL_INCLUDEDIR}/KWayland COMPONENT Devel)
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#TODO: KWidgetsAddons — Qt widget addons and dialogs. Depends on qtbase, kf6-extra-cmake-modules.
|
||||
[source]
|
||||
tar = "https://invent.kde.org/frameworks/kwidgetsaddons/-/archive/v6.10.0/kwidgetsaddons-v6.10.0.tar.gz"
|
||||
blake3 = "d617fedcaabe19edcae6a37c63da2c16a7fd0b9e4958b914181c8072b44605ab"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#TODO: KWindowSystem — window system access. Depends on qtbase, kf6-extra-cmake-modules. QML/X11/Wayland disabled.
|
||||
[source]
|
||||
tar = "https://invent.kde.org/frameworks/kwindowsystem/-/archive/v6.10.0/kwindowsystem-v6.10.0.tar.gz"
|
||||
blake3 = "c6f0cbc63a65c61fe60935a35b6db23d0afcc08cb677f0de0c9e61c6fbf08dad"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#TODO: KXmlGui — GUI framework for menu/toolbar actions from XML. Depends on kconfigwidgets, kiconthemes, ktextwidgets.
|
||||
[source]
|
||||
tar = "https://invent.kde.org/frameworks/kxmlgui/-/archive/v6.10.0/kxmlgui-v6.10.0.tar.gz"
|
||||
blake3 = "6f1d3e9fa522ba9ce3aad6a28ac830b2941df05f8291055fb5c63af63bc97725"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
# Required by konsole.
|
||||
[source]
|
||||
tar = "https://invent.kde.org/frameworks/knotifyconfig/-/archive/v6.10.0/knotifyconfig-v6.10.0.tar.gz"
|
||||
blake3 = "8dc1d1078233ae4141e0954cf27a379eaa687300ed616949380ec35eee2bad37"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
# Required by konsole for KPart terminal embedding.
|
||||
[source]
|
||||
tar = "https://invent.kde.org/frameworks/kparts/-/archive/v6.10.0/kparts-v6.10.0.tar.gz"
|
||||
blake3 = "0fac478e8690221d2d0516bb068fe5c8d0a7e681694bec2b844acf4be7173076"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#TODO: Prison — barcode/QR code framework. Build the core KF6 library now; Data Matrix, scanner, and QML paths stay disabled on Redox.
|
||||
[source]
|
||||
tar = "https://invent.kde.org/frameworks/prison/-/archive/v6.10.0/prison-v6.10.0.tar.gz"
|
||||
blake3 = "045f62daf604b098f09b45f649d50347675a932875071e2a526abca7d8cf148f"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
# UTEMPTER optional; openpty/login path expected to work on Redox via libc/pty.h.
|
||||
[source]
|
||||
tar = "https://invent.kde.org/frameworks/kpty/-/archive/v6.10.0/kpty-v6.10.0.tar.gz"
|
||||
blake3 = "189290c823e6bc564d0c2cbdc8907c1b08f9c9f27251040acfabaff9c0093c83"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#TODO: Solid — hardware discovery and power management. UDev/UPower/udisks2 backends disabled for Redox.
|
||||
[source]
|
||||
tar = "https://invent.kde.org/frameworks/solid/-/archive/v6.10.0/solid-v6.10.0.tar.gz"
|
||||
blake3 = "e8ddaa1b3ae376e81fe1c8e1d5b249e5d47c0203eb964616c121ee9d1b0284cb"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#TODO: Sonnet — spell checking framework. Depends on qtbase, kf6-ki18n, kf6-extra-cmake-modules.
|
||||
[source]
|
||||
tar = "https://invent.kde.org/frameworks/sonnet/-/archive/v6.10.0/sonnet-v6.10.0.tar.gz"
|
||||
blake3 = "f079de682151948e108cd40edead518e159a7fbe0a26542066029fb646d2371e"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
# Required by konsole for syntax highlighting.
|
||||
[source]
|
||||
tar = "https://invent.kde.org/frameworks/syntax-highlighting/-/archive/v6.10.0/syntax-highlighting-v6.10.0.tar.gz"
|
||||
blake3 = "d0c8066b71d44c9744275821b23fa02c383dac9a94c9249aeebebd34fe23e6bf"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
[source]
|
||||
tar = "https://invent.kde.org/plasma/kglobalacceld/-/archive/v6.0.0/kglobalacceld-v6.0.0.tar.gz"
|
||||
blake3 = "e56900df06a0ad3049be56da279070970401054812c6fcf9232341f5d38842c6"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
# Core5Compat is provided by qt5compat. ICU required for BiDi text rendering.
|
||||
[source]
|
||||
tar = "https://invent.kde.org/utilities/konsole/-/archive/v24.08.3/konsole-v24.08.3.tar.gz"
|
||||
blake3 = "916356009cc866bf813255d06e1a97f211a7b6aa7a2168dc7225cf2e942a8d9d"
|
||||
patches = [
|
||||
"01-optional-multimedia-printsupport-core5compat.patch",
|
||||
]
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#TODO: plasma-desktop — KDE desktop settings. Depends on plasma-workspace.
|
||||
[source]
|
||||
tar = "https://invent.kde.org/plasma/plasma-desktop/-/archive/v6.3.4/plasma-desktop-v6.3.4.tar.gz"
|
||||
blake3 = "97ca3c0f96f209d862202055fd5137886f74bf534dbdb74c63a34f005f11590d"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#TODO: Plasma Wayland Protocols — XML protocol definitions used by kwayland/KWin.
|
||||
[source]
|
||||
tar = "https://invent.kde.org/libraries/plasma-wayland-protocols/-/archive/v1.16.0/plasma-wayland-protocols-v1.16.0.tar.gz"
|
||||
blake3 = "db1b392cc82c1ef10d9360712fea77831f273f7e5a93ba1972b23be8968071ed"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
# Blockers: kwin, kf6-kio, kf6-kxmlgui, plasma-framework (all need DBus + OpenGL)
|
||||
[source]
|
||||
tar = "https://invent.kde.org/plasma/plasma-workspace/-/archive/v6.3.4/plasma-workspace-v6.3.4.tar.gz"
|
||||
blake3 = "63836bf9c103e1ccd4d59f9b79ed54c5e43025828dfabf7e7bb61ee29cd7aa93"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
|
||||
Submodule local/recipes/kde/sddm/source deleted from 63780fcd79
Submodule local/recipes/kde/sddm/source-pristine deleted from 63780fcd79
@@ -4,7 +4,6 @@
|
||||
# Required by konsole for bidirectional text rendering.
|
||||
[source]
|
||||
tar = "https://github.com/unicode-org/icu/releases/download/release-75-1/icu4c-75_1-src.tgz"
|
||||
blake3 = "4a02c9a2e790582e22233681c118f188d516be433a49ffec8bb2933809fe5fef"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
# Sensorfw disabled (Linux-specific). Dummy plugin provides no-op sensor readings.
|
||||
[source]
|
||||
tar = "https://download.qt.io/official_releases/qt/6.11/6.11.0/submodules/qtsensors-everywhere-src-6.11.0.tar.xz"
|
||||
blake3 = "c8c1effbe7f4f8b5b3856eced4d5bded8a84087110efef888a7abdbe7b06de47"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
# Redox platform detection and syscall adaptations in redox.patch
|
||||
[source]
|
||||
tar = "https://download.qt.io/official_releases/qt/6.8/6.8.2/submodules/qtbase-everywhere-src-6.8.2.tar.xz"
|
||||
blake3 = "d677019f6d2bc446110dfc803dd3a93bf2cce2672bb7a49b9217669e1c302255"
|
||||
patches = [
|
||||
"redox.patch",
|
||||
"qtwaylandscanner-null-guard-listeners.patch",
|
||||
|
||||
@@ -534,7 +534,6 @@ if(GCC)
|
||||
PROPERTIES COMPILE_OPTIONS "-fno-lto")
|
||||
endif()
|
||||
|
||||
|
||||
qt_internal_extend_target(Core
|
||||
CONDITION ( TEST_architecture_arch STREQUAL i386 ) OR
|
||||
( TEST_architecture_arch STREQUAL x86_64 ) OR
|
||||
@@ -1999,6 +1998,13 @@ qt_internal_extend_target(Core CONDITION REDOX
|
||||
io/qstorageinfo_unix.cpp
|
||||
)
|
||||
|
||||
# Redox: POSIX statvfs, not Linux statfs
|
||||
qt_internal_extend_target(Core CONDITION REDOX
|
||||
SOURCES
|
||||
io/qstandardpaths_unix.cpp
|
||||
io/qstorageinfo_unix.cpp
|
||||
)
|
||||
|
||||
qt_internal_extend_target(Core CONDITION QT_FEATURE_itemmodel
|
||||
SOURCES
|
||||
itemmodels/qabstractitemmodel.cpp itemmodels/qabstractitemmodel.h itemmodels/qabstractitemmodel_p.h
|
||||
|
||||
@@ -178,60 +178,6 @@ static_assert(std::is_signed_v<qint128>,
|
||||
|
||||
#ifndef __cplusplus
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#ifndef static_assert
|
||||
#define static_assert _Static_assert
|
||||
#endif
|
||||
|
||||
@@ -338,7 +338,6 @@ int QNativeSocketEnginePrivate::option(QNativeSocketEngine::SocketOption opt) co
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Sets the socket option \a opt to \a v.
|
||||
*/
|
||||
@@ -1122,60 +1121,6 @@ qint64 QNativeSocketEnginePrivate::nativeSendDatagram(const char *data, qint64 l
|
||||
}
|
||||
|
||||
if (msg.msg_namelen == sizeof(aa.a6)) {
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
if (header.hopLimit != -1) {
|
||||
msg.msg_controllen += CMSG_SPACE(sizeof(int));
|
||||
@@ -1185,60 +1130,6 @@ qint64 QNativeSocketEnginePrivate::nativeSendDatagram(const char *data, qint64 l
|
||||
memcpy(CMSG_DATA(cmsgptr), &header.hopLimit, sizeof(int));
|
||||
cmsgptr = reinterpret_cast<cmsghdr *>(reinterpret_cast<char *>(cmsgptr) + CMSG_SPACE(sizeof(int)));
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
if (header.ifindex != 0 || !header.senderAddress.isNull()) {
|
||||
struct in6_pktinfo *data = reinterpret_cast<in6_pktinfo *>(CMSG_DATA(cmsgptr));
|
||||
|
||||
@@ -22,60 +22,6 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#if defined(Q_OS_VXWORKS)
|
||||
|
||||
-216
@@ -52,116 +52,8 @@ public:
|
||||
virtual bool supportsWindowDecoration() const { return false; }
|
||||
|
||||
virtual QWaylandWindow *createEglWindow(QWindow *window) = 0;
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
virtual QPlatformOpenGLContext *createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const = 0;
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
virtual bool canCreatePlatformOffscreenSurface() const { return false; }
|
||||
#if QT_CONFIG(opengl)
|
||||
@@ -175,117 +67,9 @@ public:
|
||||
EglContext
|
||||
};
|
||||
virtual void *nativeResource(NativeResource /*resource*/) { return nullptr; }
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
virtual void *nativeResourceForContext(NativeResource /*resource*/, QPlatformOpenGLContext */*context*/) { return nullptr; }
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -42,10 +42,10 @@ set(CMAKE_SYSTEM_VERSION 1)
|
||||
|
||||
# Redox userspace currently must not emit CET/IBT entry instructions (endbr64),
|
||||
# because they trap as invalid opcode in the current runtime stack.
|
||||
set(CMAKE_C_FLAGS "-fcf-protection=none -march=x86-64 -include strings.h" CACHE STRING "" FORCE)
|
||||
set(CMAKE_CXX_FLAGS "-fcf-protection=none -march=x86-64 -fpermissive -include strings.h -I${COOKBOOK_SYSROOT}/usr/include/QtQml -I${COOKBOOK_SYSROOT}/usr/include/QtQuick" CACHE STRING "" FORCE)
|
||||
set(CMAKE_C_FLAGS_RELEASE "-fcf-protection=none -march=x86-64 -include strings.h" CACHE STRING "" FORCE)
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-fcf-protection=none -march=x86-64 -fpermissive -include strings.h" CACHE STRING "" FORCE)
|
||||
set(CMAKE_C_FLAGS "-fcf-protection=none -march=x86-64 -include strings.h -D_GLIBCXX_HOSTED=1" CACHE STRING "" FORCE)
|
||||
set(CMAKE_CXX_FLAGS "-fcf-protection=none -march=x86-64 -fpermissive -include strings.h -D_GLIBCXX_HOSTED=1 -I${COOKBOOK_SYSROOT}/usr/include/QtQml -I${COOKBOOK_SYSROOT}/usr/include/QtQuick" CACHE STRING "" FORCE)
|
||||
set(CMAKE_C_FLAGS_RELEASE "-fcf-protection=none -march=x86-64 -include strings.h -D_GLIBCXX_HOSTED=1" CACHE STRING "" FORCE)
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-fcf-protection=none -march=x86-64 -fpermissive -include strings.h -D_GLIBCXX_HOSTED=1" CACHE STRING "" FORCE)
|
||||
|
||||
# Flag for redox.patch: enables REDOX-specific CMake code paths (mkspec, QPA plugin).
|
||||
# QtPlatformSupport.cmake checks this variable. Set as CACHE INTERNAL so it persists
|
||||
|
||||
@@ -103,3 +103,26 @@ match.product_name = "17U70P"
|
||||
[[dmi_system_quirk]]
|
||||
flags = ["kbd_deactivate_fixup"]
|
||||
match.sys_vendor = "LG Electronics"
|
||||
|
||||
# Dell: same i8042 keyboard IRQ + atkbd quirks (Linux
|
||||
# drivers/platform/x86/dell/dell-laptop.c and atkbd.c
|
||||
# cover the full Dell lineup). Modern Standby on
|
||||
# Dell XPS 13 Plus / Latitude 7440 / Inspiron 14 Plus.
|
||||
# Hardware-agnostic: applies to all Dell Inc systems.
|
||||
[[dmi_system_quirk]]
|
||||
flags = ["kbd_deactivate_fixup", "acpi_irq1_skip_override"]
|
||||
match.sys_vendor = "Dell Inc."
|
||||
|
||||
# HP: same i8042 / atkbd quirks. Modern Standby on
|
||||
# HP Spectre x360 14 / EliteBook 840 G10 / Pavilion Aero 13.
|
||||
# Hardware-agnostic: applies to all HP systems.
|
||||
[[dmi_system_quirk]]
|
||||
flags = ["kbd_deactivate_fixup", "acpi_irq1_skip_override"]
|
||||
match.sys_vendor = "HP"
|
||||
|
||||
# Lenovo: same i8042 / atkbd quirks. Modern Standby on
|
||||
# ThinkPad X1 Carbon Gen 12 / Yoga Slim 7 / IdeaPad Slim 7i.
|
||||
# Hardware-agnostic: applies to all Lenovo systems.
|
||||
[[dmi_system_quirk]]
|
||||
flags = ["kbd_deactivate_fixup", "acpi_irq1_skip_override"]
|
||||
match.sys_vendor = "LENOVO"
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
# redox.patch restores the Redox compatibility stubs plus Meson scanner detection.
|
||||
[source]
|
||||
tar = "https://gitlab.freedesktop.org/wayland/wayland/-/releases/1.24.0/downloads/wayland-1.24.0.tar.xz"
|
||||
blake3 = "8c3b2bc792e5e262e9fb821fb8222b376de6fdf5d7af9b86d46e51ecf79704b9"
|
||||
patches = ["redox.patch"]
|
||||
|
||||
[build]
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
# seatd provides a seat management daemon used by Wayland compositors
|
||||
[source]
|
||||
tar = "https://git.sr.ht/~kennylevinsen/seatd/archive/0.9.1.tar.gz"
|
||||
blake3 = "0bca2188cb2f56d7d50774657435db9e5ead358854cfbde8c4d7d6504929a49f"
|
||||
|
||||
[build]
|
||||
template = "meson"
|
||||
|
||||
Submodule local/reference/linux-7.1 deleted from ab9de95c9c
Submodule local/reference/seL4 deleted from a0b4f2d25d
Executable
+161
@@ -0,0 +1,161 @@
|
||||
#!/usr/bin/env bash
|
||||
# check-cargo-patches.sh — verify all [patch.crates-io] and [patch."<URL>"]
|
||||
# sections in local sources' Cargo.toml resolve to the expected paths.
|
||||
#
|
||||
# Scans local/sources/*/Cargo.toml for [patch.*] sections and runs
|
||||
# `cargo metadata` on each source to confirm the patch is applied
|
||||
# (i.e. the resolved source URL matches the expected local path).
|
||||
#
|
||||
# This is the Phase J / Improvement C verification step. The cookbook's
|
||||
# own patch validation handles file-level patches; this script handles
|
||||
# the Cargo-level [patch] sections which are needed for transitive
|
||||
# deps like redox_syscall, libredox, etc.
|
||||
#
|
||||
# Usage: ./local/scripts/check-cargo-patches.sh [--strict]
|
||||
# --strict: exit non-zero if any patch fails verification (for CI)
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
|
||||
STRICT=false
|
||||
[[ "${1:-}" == "--strict" ]] && STRICT=true
|
||||
|
||||
PASSED=0
|
||||
FAILED=0
|
||||
SKIPPED=0
|
||||
|
||||
echo "=== Cargo [patch] Verification ==="
|
||||
|
||||
# Find all Cargo.toml files in local sources
|
||||
# Skip relibc explicitly — its [patch] section is only the
|
||||
# cc-rs git branch override (no `path` patches), and
|
||||
# `cargo metadata` on relibc takes minutes (hundreds of
|
||||
# deps) which would hang the script.
|
||||
while IFS= read -r -d '' cargo_toml; do
|
||||
case "$cargo_toml" in
|
||||
*local/sources/relibc/Cargo.toml) continue ;;
|
||||
esac
|
||||
source_dir="$(dirname "$cargo_toml")"
|
||||
source_name="$(basename "$source_dir")"
|
||||
relative_to_root="${cargo_toml#$ROOT/}"
|
||||
|
||||
# Find [patch.crates-io] and [patch."<URL>"] sections
|
||||
patch_lines=$(grep -E '^\[patch\.' "$cargo_toml" 2>/dev/null || true)
|
||||
if [[ -z "$patch_lines" ]]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "--- $relative_to_root ---"
|
||||
echo " $patch_lines" | sed 's/^/ /'
|
||||
|
||||
# Check if the source is a workspace member
|
||||
if ! grep -q '^\[workspace\]' "$cargo_toml" 2>/dev/null; then
|
||||
# Single-package — [patch] sections need [workspace] to apply
|
||||
# (cargo treats them as ignored). This is a common bug.
|
||||
if grep -q '^\[patch\.' "$cargo_toml" 2>/dev/null; then
|
||||
echo " ⚠️ WARN: source has [patch] sections but no [workspace]"
|
||||
echo " cargo silently ignores [patch] in non-workspace manifests"
|
||||
SKIPPED=$((SKIPPED + 1))
|
||||
fi
|
||||
continue
|
||||
fi
|
||||
|
||||
# Check if cargo is available
|
||||
if ! command -v cargo >/dev/null 2>&1; then
|
||||
echo " SKIP: cargo not available"
|
||||
SKIPPED=$((SKIPPED + 1))
|
||||
continue
|
||||
fi
|
||||
|
||||
# Run cargo metadata and parse the resolved source URLs.
|
||||
# Use a 30-second timeout to prevent hangs on large
|
||||
# workspaces like relibc (which has hundreds of deps).
|
||||
if ! timeout 30 cargo metadata --format-version 1 --manifest-path "$cargo_toml" >/dev/null 2>&1; then
|
||||
echo " SKIP: cargo metadata timed out (30s)"
|
||||
SKIPPED=$((SKIPPED + 1))
|
||||
continue
|
||||
fi
|
||||
|
||||
# Extract the resolved source URLs and check against the
|
||||
# expected [patch] paths. The expected [patch] entries have
|
||||
# a `path = "..."` field; the resolved source URL from
|
||||
# cargo metadata should match the local path.
|
||||
expected_paths=$(grep -A1 '^\[patch\.' "$cargo_toml" 2>/dev/null | grep -oP 'path\s*=\s*"\K[^"]+' | sort -u)
|
||||
if [[ -z "$expected_paths" ]]; then
|
||||
# No `path` entries in the [patch] sections. This is
|
||||
# common for git-branch patches (e.g. relibc's cc-rs).
|
||||
# The verification only applies to `path` patches.
|
||||
# Continue to next file.
|
||||
continue
|
||||
fi
|
||||
|
||||
resolved_urls=$(cargo metadata --format-version 1 --manifest-path "$cargo_toml" 2>/dev/null \
|
||||
| python3 -c '
|
||||
import json, sys
|
||||
data = json.load(sys.stdin)
|
||||
# For path-deps, source is null but manifest_path points to
|
||||
# the local fork. Print both forms.
|
||||
for pkg in data.get("packages", []):
|
||||
src = pkg.get("source", "")
|
||||
if src:
|
||||
print(src)
|
||||
mp = pkg.get("manifest_path", "")
|
||||
if mp:
|
||||
print(mp)
|
||||
' 2>/dev/null | sort -u)
|
||||
|
||||
good=0
|
||||
bad=0
|
||||
# Skip the resolution loop if there are no `path` entries.
|
||||
# (Empty `expected_paths` would loop with empty lines.)
|
||||
if [[ -n "$expected_paths" ]]; then
|
||||
while IFS= read -r expected; do
|
||||
# Skip empty lines (the heredoc may emit one)
|
||||
if [[ -z "$expected" ]]; then
|
||||
continue
|
||||
fi
|
||||
# expected is a path like "../syscall" or "../libredox"
|
||||
# Resolve to absolute
|
||||
expected_abs="$(cd "$source_dir" && realpath "$expected" 2>/dev/null || echo "")"
|
||||
if [[ -z "$expected_abs" ]]; then
|
||||
continue
|
||||
fi
|
||||
if echo "$resolved_urls" | grep -qF "$expected_abs"; then
|
||||
good=$((good + 1))
|
||||
else
|
||||
# Check if the expected path is the source itself
|
||||
if [[ "$expected_abs" == "$source_dir" ]]; then
|
||||
# self-patch is OK
|
||||
good=$((good + 1))
|
||||
else
|
||||
bad=$((bad + 1))
|
||||
echo " ⚠️ [patch] path $expected → $expected_abs NOT in resolved sources"
|
||||
fi
|
||||
fi
|
||||
done <<< "$expected_paths"
|
||||
fi
|
||||
|
||||
if [[ $bad -eq 0 ]]; then
|
||||
echo " ✅ All $good [patch] entries resolved correctly"
|
||||
PASSED=$((PASSED + 1))
|
||||
else
|
||||
echo " ❌ $bad [patch] entries did not resolve"
|
||||
FAILED=$((FAILED + 1))
|
||||
fi
|
||||
done < <(find "$ROOT/local/sources" -name 'Cargo.toml' -print0 2>/dev/null)
|
||||
|
||||
echo ""
|
||||
echo "=== Summary ==="
|
||||
echo " Passed: $PASSED"
|
||||
echo " Failed: $FAILED"
|
||||
echo " Skipped: $SKIPPED"
|
||||
if [[ $FAILED -gt 0 ]]; then
|
||||
echo ""
|
||||
echo "❌ Cargo [patch] verification FAILED"
|
||||
$STRICT && exit 1
|
||||
exit 1
|
||||
fi
|
||||
echo ""
|
||||
echo "✅ Cargo [patch] verification PASSED"
|
||||
exit 0
|
||||
Executable
+183
@@ -0,0 +1,183 @@
|
||||
#!/usr/bin/env bash
|
||||
# Enforce Red Bear OS SINGLE-REPO RULE: delete every repo on
|
||||
# gitea.redbearos.org/vasilito/ except RedBear-OS and hiperiso.
|
||||
#
|
||||
# Token is read at runtime from $REDBEAR_GITEA_TOKEN (or ~/.netrc or
|
||||
# git credential helper). It is NEVER written to disk, logged, or echoed.
|
||||
# See local/AGENTS.md § Token Policy.
|
||||
#
|
||||
# Usage:
|
||||
# ./local/scripts/delete-per-component-repos.sh # interactive
|
||||
# ./local/scripts/delete-per-component-repos.sh --dry-run # list only
|
||||
# ./local/scripts/delete-per-component-repos.sh --yes # no prompts
|
||||
# ./local/scripts/delete-per-component-repos.sh --only redbear-os-base,redox-drm
|
||||
# ./local/scripts/delete-per-component-repos.sh -h # this help
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
GITEA_HOST="${GITEA_HOST:-https://gitea.redbearos.org}"
|
||||
GITEA_USER="${GITEA_USER:-vasilito}"
|
||||
CANONICAL_REPO="${CANONICAL_REPO:-RedBear-OS}"
|
||||
KEEP_ALWAYS="${KEEP_ALWAYS:-${CANONICAL_REPO} hiperiso}"
|
||||
|
||||
DRY_RUN=0
|
||||
ASSUME_YES=0
|
||||
ONLY_LIST=""
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--dry-run) DRY_RUN=1 ;;
|
||||
--yes|-y) ASSUME_YES=1 ;;
|
||||
--only) shift; ONLY_LIST="${1:-}" ;;
|
||||
-h|--help)
|
||||
sed -n '2,28p' "$0"
|
||||
exit 0 ;;
|
||||
*) echo "ERROR: unknown arg: $1" >&2; exit 2 ;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
log() { printf '[delete-per-component-repos] %s\n' "$*" >&2; }
|
||||
die() { log "FATAL: $*"; exit 1; }
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 1. Locate the token — env var, .netrc, or git credential helper (in order).
|
||||
# Never echo it, never log it, never write it to disk.
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
resolve_token() {
|
||||
if [ -n "${REDBEAR_GITEA_TOKEN:-}" ]; then
|
||||
printf '%s' "$REDBEAR_GITEA_TOKEN"
|
||||
return 0
|
||||
fi
|
||||
if command -v git >/dev/null 2>&1; then
|
||||
local helper_token
|
||||
helper_token="$(git credential fill <<EOF 2>/dev/null | sed -n 's/^password=//p' | head -n1
|
||||
protocol=https
|
||||
host=gitea.redbearos.org
|
||||
username=${GITEA_USER}
|
||||
EOF
|
||||
)"
|
||||
if [ -n "$helper_token" ]; then
|
||||
printf '%s' "$helper_token"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
if [ -r "$HOME/.netrc" ]; then
|
||||
local netrc_token
|
||||
netrc_token="$(awk -v host="gitea.redbearos.org" -v user="$GITEA_USER" '
|
||||
$1=="machine" && $2==host { in_block=1; next }
|
||||
in_block && $1=="login" && $2==user { want=1; next }
|
||||
in_block && want && $1=="password" { print $2; exit }
|
||||
in_block && $1=="machine" { in_block=0 }
|
||||
' "$HOME/.netrc")"
|
||||
if [ -n "$netrc_token" ]; then
|
||||
printf '%s' "$netrc_token"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
log "Resolving Gitea token (env → git helper → ~/.netrc) ..."
|
||||
TOKEN="$(resolve_token || true)"
|
||||
[ -n "$TOKEN" ] || die "no token found. Set REDBEAR_GITEA_TOKEN or configure ~/.netrc / git credential helper."
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 2. List every repo visible to the user via the Gitea API.
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
api_get() {
|
||||
curl -fsS -H "Authorization: token $TOKEN" \
|
||||
-H "Accept: application/json" \
|
||||
"$GITEA_HOST/api/v1$1"
|
||||
}
|
||||
|
||||
log "Fetching repo list from ${GITEA_HOST}/api/v1/users/${GITEA_USER}/repos ..."
|
||||
REPOS_JSON="$(api_get "/users/${GITEA_USER}/repos?limit=200")" || die "Gitea API call failed."
|
||||
|
||||
REPOS_ALL="$(printf '%s' "$REPOS_JSON" | jq -r '.[].name')"
|
||||
[ -n "$REPOS_ALL" ] || die "no repos returned — check token permissions."
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 3. Filter the deletion candidates.
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
CANDIDATES=""
|
||||
while IFS= read -r repo; do
|
||||
[ -n "$repo" ] || continue
|
||||
case " $KEEP_ALWAYS " in
|
||||
*" $repo "*) continue ;; # canonical + user-named keepers
|
||||
esac
|
||||
if [ -n "$ONLY_LIST" ]; then
|
||||
# comma-separated whitelist
|
||||
case ",$ONLY_LIST," in
|
||||
*",$repo,"*) ;; # match
|
||||
*) continue ;;
|
||||
esac
|
||||
fi
|
||||
CANDIDATES="${CANDIDATES}${repo}"$'\n'
|
||||
done <<< "$REPOS_ALL"
|
||||
|
||||
CANDIDATES="$(printf '%s' "$CANDIDATES" | sed '/^$/d')"
|
||||
|
||||
if [ -z "$CANDIDATES" ]; then
|
||||
log "No repos match deletion criteria. Nothing to do."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
log "Repos flagged for deletion:"
|
||||
while IFS= read -r r; do
|
||||
[ -n "$r" ] || continue
|
||||
log " - $r"
|
||||
done <<< "$CANDIDATES"
|
||||
|
||||
if [ "$DRY_RUN" -eq 1 ]; then
|
||||
log "Dry run — no deletions performed."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 4. Confirm with the operator (unless --yes).
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
if [ "$ASSUME_YES" -ne 1 ]; then
|
||||
log ""
|
||||
log "WARNING: This DELETES repositories from ${GITEA_HOST}."
|
||||
log "Make sure each repo above has been migrated as a submodule branch"
|
||||
log "inside ${CANONICAL_REPO} first (see redirect-to-submodules.sh)."
|
||||
log "The deletion is irreversible."
|
||||
log ""
|
||||
read -r -p "Type 'delete' to confirm: " confirm
|
||||
if [ "$confirm" != "delete" ]; then
|
||||
log "Aborted."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 5. Delete each candidate via DELETE /repos/{owner}/{repo}.
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
fail_count=0
|
||||
ok_count=0
|
||||
while IFS= read -r repo; do
|
||||
[ -n "$repo" ] || continue
|
||||
log "Deleting ${GITEA_USER}/${repo} ..."
|
||||
http_code="$(curl -sS -o /dev/null -w '%{http_code}' \
|
||||
-X DELETE \
|
||||
-H "Authorization: token $TOKEN" \
|
||||
-H "Accept: application/json" \
|
||||
"${GITEA_HOST}/api/v1/repos/${GITEA_USER}/${repo}")"
|
||||
case "$http_code" in
|
||||
2*) log " ✓ deleted ($http_code)"; ok_count=$((ok_count+1)) ;;
|
||||
403) log " ✗ FORBIDDEN — token lacks delete permission on ${repo}"; fail_count=$((fail_count+1)) ;;
|
||||
404) log " – already gone (404)"; ok_count=$((ok_count+1)) ;;
|
||||
*) log " ✗ FAILED ($http_code)"; fail_count=$((fail_count+1)) ;;
|
||||
esac
|
||||
done <<< "$CANDIDATES"
|
||||
|
||||
log ""
|
||||
log "Summary: ${ok_count} deleted, ${fail_count} failed."
|
||||
[ "$fail_count" -eq 0 ] || exit 3
|
||||
exit 0
|
||||
Executable
+185
@@ -0,0 +1,185 @@
|
||||
#!/usr/bin/env bash
|
||||
# Redirect each existing per-component Gitea repo into a branch on the
|
||||
# canonical RedBear-OS repo, then point the matching git submodule(s) at
|
||||
# that branch. After this, the per-component Gitea repos can be deleted
|
||||
# without breaking any submodule resolution.
|
||||
#
|
||||
# What this script does, for each per-component Gitea repo:
|
||||
# 1. Fetches the repo's HEAD into a temp clone.
|
||||
# 2. Pushes that HEAD as a `submodule/<component>` branch on RedBear-OS.
|
||||
# 3. Rewrites `.gitmodules` so any submodule entry pointing at the
|
||||
# per-component URL now points at RedBear-OS with the new branch.
|
||||
#
|
||||
# What it does NOT do:
|
||||
# - It does not move source content between repositories (source already
|
||||
# lives in the per-component repo; we just push it under a new branch
|
||||
# name in the canonical repo).
|
||||
# - It does not delete the per-component Gitea repos. Use
|
||||
# delete-per-component-repos.sh afterwards.
|
||||
# - It does not touch recipe.toml files (none reference the per-component
|
||||
# URLs as far as the current tree shows).
|
||||
#
|
||||
# Token is read at runtime from $REDBEAR_GITEA_TOKEN (or ~/.netrc). It is
|
||||
# NEVER written to disk, logged, or echoed.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
GITEA_HOST="${GITEA_HOST:-https://gitea.redbearos.org}"
|
||||
GITEA_USER="${GITEA_USER:-vasilito}"
|
||||
CANONICAL_REPO="${CANONICAL_REPO:-RedBear-OS}"
|
||||
CANONICAL_URL="${CANONICAL_URL:-${GITEA_HOST}/${GITEA_USER}/${CANONICAL_REPO}.git}"
|
||||
|
||||
# Per-component Gitea repos to redirect. The actual Gitea slug is
|
||||
# discovered at runtime via the API, so this list contains the canonical
|
||||
# component names only.
|
||||
DEFAULT_COMPONENTS=(base kernel installer redox-drm userutils libredox libpciaccess)
|
||||
|
||||
DRY_RUN=0
|
||||
SKIP_PUSH=0
|
||||
COMPONENTS=()
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--dry-run) DRY_RUN=1 ;;
|
||||
--skip-push) SKIP_PUSH=1 ;;
|
||||
-h|--help) sed -n '2,28p' "$0"; exit 0 ;;
|
||||
--) shift; while [ $# -gt 0 ]; do COMPONENTS+=("$1"); shift; done ;;
|
||||
-*) echo "ERROR: unknown arg: $1" >&2; exit 2 ;;
|
||||
*) COMPONENTS+=("$1") ;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
[ "${#COMPONENTS[@]}" -gt 0 ] || COMPONENTS=("${DEFAULT_COMPONENTS[@]}")
|
||||
|
||||
log() { printf '[redirect-to-submodules] %s\n' "$*" >&2; }
|
||||
die() { log "FATAL: $*"; exit 1; }
|
||||
|
||||
resolve_token() {
|
||||
if [ -n "${REDBEAR_GITEA_TOKEN:-}" ]; then
|
||||
printf '%s' "$REDBEAR_GITEA_TOKEN"
|
||||
return 0
|
||||
fi
|
||||
if [ -r "$HOME/.netrc" ]; then
|
||||
awk -v host="gitea.redbearos.org" -v user="$GITEA_USER" '
|
||||
$1=="machine" && $2==host { in_block=1; next }
|
||||
in_block && $1=="login" && $2==user { want=1; next }
|
||||
in_block && want && $1=="password" { print $2; exit }
|
||||
in_block && $1=="machine" { in_block=0 }
|
||||
' "$HOME/.netrc"
|
||||
fi
|
||||
}
|
||||
|
||||
TOKEN="$(resolve_token || true)"
|
||||
[ -n "$TOKEN" ] || die "no token found. Set REDBEAR_GITEA_TOKEN or configure ~/.netrc."
|
||||
|
||||
command -v git >/dev/null || die "git not found in PATH"
|
||||
command -v jq >/dev/null || die "jq not found in PATH"
|
||||
git rev-parse --is-inside-work-tree >/dev/null 2>&1 || die "must be run from inside the ${CANONICAL_REPO} working tree"
|
||||
|
||||
current_branch="$(git rev-parse --abbrev-ref HEAD)"
|
||||
log "Working tree : $(git rev-parse --show-toplevel)"
|
||||
log "Branch : ${current_branch}"
|
||||
log "Canonical URL: ${CANONICAL_URL}"
|
||||
|
||||
if [ "$DRY_RUN" -eq 0 ] && [ "$SKIP_PUSH" -eq 0 ]; then
|
||||
log ""
|
||||
log "This script PUSHES branches to ${CANONICAL_URL} and modifies .gitmodules."
|
||||
read -r -p "Type 'redirect' to confirm: " confirm
|
||||
[ "$confirm" = "redirect" ] || { log "Aborted."; exit 1; }
|
||||
fi
|
||||
|
||||
api_get() {
|
||||
curl -fsS -H "Authorization: token $TOKEN" \
|
||||
-H "Accept: application/json" \
|
||||
"$GITEA_HOST/api/v1$1"
|
||||
}
|
||||
|
||||
log "Verifying Gitea credentials ..."
|
||||
api_get "/user" >/dev/null || die "token rejected by Gitea API"
|
||||
|
||||
log "Fetching Gitea repo list ..."
|
||||
REPO_NAMES_API="$(api_get "/users/${GITEA_USER}/repos?limit=200" | jq -r '.[].name')"
|
||||
[ -n "${REPO_NAMES_API}" ] || die "no repos returned — check token permissions."
|
||||
|
||||
find_slug() {
|
||||
local component="$1"
|
||||
# Try the legacy redbear-os-<component> convention first, then the bare name.
|
||||
for candidate in "redbear-os-${component}" "${component}"; do
|
||||
if printf '%s\n' "${REPO_NAMES_API}" | grep -qx "${candidate}"; then
|
||||
printf '%s' "${candidate}"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
redirect_component() {
|
||||
local component="$1"
|
||||
local gitea_slug
|
||||
if ! gitea_slug="$(find_slug "${component}")"; then
|
||||
log ""
|
||||
log "=== ${component} ==="
|
||||
die "no Gitea repo found for component '${component}' (tried: redbear-os-${component}, ${component})"
|
||||
fi
|
||||
local branch="submodule/${component}"
|
||||
|
||||
log ""
|
||||
log "=== ${component} ==="
|
||||
log " source Gitea repo : ${gitea_slug}"
|
||||
log " target branch : ${branch}"
|
||||
|
||||
if [ "$DRY_RUN" -eq 1 ]; then
|
||||
log " [dry-run] would fetch HEAD, push as ${branch}, rewrite .gitmodules"
|
||||
return 0
|
||||
fi
|
||||
|
||||
local tmp
|
||||
tmp="$(mktemp -d)"
|
||||
trap 'rm -rf "$tmp"' EXIT
|
||||
|
||||
log " cloning ${gitea_slug} ..."
|
||||
local src_url="https://${TOKEN}@${GITEA_HOST#https://}/${GITEA_USER}/${gitea_slug}.git"
|
||||
git clone --quiet "${src_url}" "${tmp}/src" \
|
||||
|| die "clone failed for ${gitea_slug}"
|
||||
|
||||
local src_default
|
||||
src_default="$(git -C "${tmp}/src" symbolic-ref --short HEAD 2>/dev/null || echo "")"
|
||||
local src_commit_count
|
||||
src_commit_count="$(git -C "${tmp}/src" rev-list --all --count 2>/dev/null || echo 0)"
|
||||
if [ -z "${src_commit_count}" ] || [ "${src_commit_count}" = "0" ]; then
|
||||
log " source repo is empty (0 commits) — skipping push"
|
||||
rm -rf "${tmp}"
|
||||
trap - EXIT
|
||||
log " ✓ ${component} (no-op)"
|
||||
return 0
|
||||
fi
|
||||
log " source default branch: ${src_default} (${src_commit_count} commits)"
|
||||
log " pushing ${branch} to ${CANONICAL_URL} ..."
|
||||
local push_url="https://${TOKEN}@${GITEA_HOST#https://}/${GITEA_USER}/${CANONICAL_REPO}.git"
|
||||
git -C "${tmp}/src" push --quiet "${push_url}" "refs/heads/${src_default}:refs/heads/${branch}" \
|
||||
|| die "push failed for ${branch}"
|
||||
|
||||
log " rewriting .gitmodules ..."
|
||||
if grep -q "url = .*${gitea_slug}\.git" .gitmodules 2>/dev/null; then
|
||||
sed -i.bak "s|url = .*${gitea_slug}\.git|url = ${CANONICAL_URL}|" .gitmodules
|
||||
sed -i "s|^ branch = .*| branch = ${branch}|" .gitmodules
|
||||
rm -f .gitmodules.bak
|
||||
log " updated"
|
||||
else
|
||||
log " no .gitmodules entry references ${gitea_slug}; left untouched"
|
||||
fi
|
||||
|
||||
rm -rf "${tmp}"
|
||||
trap - EXIT
|
||||
log " ✓ ${component} redirected"
|
||||
}
|
||||
|
||||
for c in "${COMPONENTS[@]}"; do
|
||||
redirect_component "$c"
|
||||
done
|
||||
|
||||
log ""
|
||||
log "Done. Verify with: git submodule status"
|
||||
log "Then run ./local/scripts/delete-per-component-repos.sh to delete the"
|
||||
log "now-unused per-component repos on Gitea."
|
||||
+1
-1
Submodule local/sources/base updated: c335553c7e...25a988a15d
Submodule local/sources/ctrlc deleted from 3d2b25113a
+1
-1
Submodule local/sources/kernel updated: 7a38664253...d41d0aa728
Submodule local/sources/libpciaccess deleted from 1c33262e23
Submodule
+1
Submodule local/sources/libredox added at 8a4014fb3c
Submodule local/sources/redox-drm deleted from 02b05407fe
+1
-1
Submodule local/sources/relibc updated: a725e6ac8c...620184ab6d
Submodule
+1
Submodule local/sources/syscall added at b0f4fee4c4
Submodule local/sources/sysinfo deleted from ee923581fb
+74
-39
@@ -510,6 +510,53 @@ pub fn fetch_offline(recipe: &CookRecipe, logger: &PtyOut) -> Result<FetchResult
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
/// Clone a fresh source directory for a git-sourced recipe. Used both on
|
||||
/// the initial fetch path and on the self-heal path when the existing
|
||||
/// source dir has lost its embedded .git directory (e.g., a cleanup pass
|
||||
/// removed it). After this returns, `source_dir` exists with a valid
|
||||
/// `.git` pointing at the recipe's `git` URL on `rev`/`branch`.
|
||||
fn reclone_git_source(
|
||||
recipe_dir: &Path,
|
||||
source_dir: &Path,
|
||||
git: &str,
|
||||
branch: &Option<String>,
|
||||
shallow_clone: bool,
|
||||
logger: &PtyOut,
|
||||
) -> Result<()> {
|
||||
let source_dir_tmp = recipe_dir.join("source.tmp");
|
||||
if source_dir_tmp.exists() {
|
||||
std::fs::remove_dir_all(&source_dir_tmp).ok();
|
||||
}
|
||||
create_dir_clean(&source_dir_tmp)?;
|
||||
|
||||
let mut command = Command::new("git");
|
||||
command
|
||||
.arg("clone")
|
||||
.arg("--recursive")
|
||||
.arg(translate_mirror(git));
|
||||
if let Some(branch) = branch {
|
||||
command.arg("--branch").arg(branch);
|
||||
}
|
||||
if shallow_clone {
|
||||
command
|
||||
.arg("--filter=tree:0")
|
||||
.arg("--also-filter-submodules");
|
||||
}
|
||||
command.arg(&source_dir_tmp);
|
||||
if let Err(e) = run_command(command, logger) {
|
||||
if !is_redox() {
|
||||
return Err(e);
|
||||
}
|
||||
let mut cmds = vec!["update", "--init"];
|
||||
if shallow_clone {
|
||||
cmds.push("--filter=tree:0");
|
||||
}
|
||||
manual_git_recursive_submodule(logger, &source_dir_tmp, cmds)?;
|
||||
}
|
||||
rename(&source_dir_tmp, source_dir)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn fetch(recipe: &CookRecipe, check_source: bool, logger: &PtyOut) -> Result<FetchResult> {
|
||||
if redbear_protected_recipe(recipe.name.name()) && !redbear_allow_protected_fetch() {
|
||||
log_to_pty!(
|
||||
@@ -587,51 +634,39 @@ pub fn fetch(recipe: &CookRecipe, check_source: bool, logger: &PtyOut) -> Result
|
||||
//TODO: use libgit?
|
||||
let shallow_clone = *shallow_clone == Some(true);
|
||||
let cached = if !source_dir.is_dir() {
|
||||
// Create source.tmp
|
||||
let source_dir_tmp = recipe_dir.join("source.tmp");
|
||||
create_dir_clean(&source_dir_tmp)?;
|
||||
|
||||
// Clone the repository to source.tmp
|
||||
let mut command = Command::new("git");
|
||||
command
|
||||
.arg("clone")
|
||||
.arg("--recursive")
|
||||
.arg(translate_mirror(&git));
|
||||
if let Some(branch) = branch {
|
||||
command.arg("--branch").arg(branch);
|
||||
}
|
||||
if shallow_clone {
|
||||
command
|
||||
.arg("--filter=tree:0")
|
||||
.arg("--also-filter-submodules");
|
||||
}
|
||||
command.arg(&source_dir_tmp);
|
||||
if let Err(e) = run_command(command, logger) {
|
||||
if !is_redox() {
|
||||
return Err(e);
|
||||
}
|
||||
// TODO: RedoxFS has a race condition problem with `--recursive` and running in multi CPU.
|
||||
// It is appear that running the submodule update separately fixes it. Remove this when
|
||||
// `git clone https://gitlab.redox-os.org/redox-os/relibc --recursive` proven to work in Redox OS.
|
||||
let mut cmds = vec!["update", "--init"];
|
||||
if shallow_clone {
|
||||
cmds.push("--filter=tree:0");
|
||||
}
|
||||
manual_git_recursive_submodule(logger, &source_dir_tmp, cmds)?;
|
||||
}
|
||||
|
||||
// Move source.tmp to source atomically
|
||||
rename(&source_dir_tmp, &source_dir)?;
|
||||
|
||||
reclone_git_source(
|
||||
&recipe_dir,
|
||||
&source_dir,
|
||||
&git,
|
||||
&branch,
|
||||
shallow_clone,
|
||||
logger,
|
||||
)?;
|
||||
false
|
||||
} else if !check_source {
|
||||
true
|
||||
} else {
|
||||
if !source_dir.join(".git").is_dir() {
|
||||
bail_other_err!(
|
||||
"{:?} is not a git repository, but recipe indicated git source",
|
||||
source_dir.display()
|
||||
// Self-heal: source dir exists but has no .git (e.g., a
|
||||
// cleanup pass removed embedded .git directories from
|
||||
// build-cache sources, or the dir was extracted from an
|
||||
// archive). Wipe and re-clone from the recipe's git URL
|
||||
// instead of hard-failing — without this, every damaged
|
||||
// build-cache source required manual intervention.
|
||||
log_to_pty!(
|
||||
logger,
|
||||
" source dir {:?} exists but has no .git; re-cloning from {:?}",
|
||||
source_dir.display(),
|
||||
git
|
||||
);
|
||||
reclone_git_source(
|
||||
&recipe_dir,
|
||||
&source_dir,
|
||||
&git,
|
||||
&branch,
|
||||
shallow_clone,
|
||||
logger,
|
||||
)?;
|
||||
}
|
||||
|
||||
// Reset origin
|
||||
|
||||
Reference in New Issue
Block a user