feat: build system transition to release fork + archive hardening
Release fork infrastructure: - REDBEAR_RELEASE=0.1.1 with offline enforcement (fetch/distclean/unfetch blocked) - 195 BLAKE3-verified source archives in standard format - Atomic provisioning via provision-release.sh (staging + .complete sentry) - 5-phase improvement plan: restore format auto-detection, source tree validation (validate-source-trees.py), archive-map.json, REPO_BINARY fallback Archive normalization: - Removed 87 duplicate/unversioned archives from shared pool - Regenerated all archives in consistent format with source/ + recipe.toml - BLAKE3SUMS and manifest.json generated from stable tarball set Patch management: - verify-patches.sh: pre-sync dry-run report (OK/REVERSED/CONFLICT) - 121 upstream-absorbed patches moved to absorbed/ directories - 43 active patches verified clean against rebased sources - Stress test: base updated to upstream HEAD, relibc reset and patched Compilation fixes: - relibc: Vec imports in redox-rt (proc.rs, lib.rs, sys.rs) - relibc: unsafe from_raw_parts in mod.rs (2024 edition) - fetch.rs: rev comparison handles short/full hash prefixes - kibi recipe: corrected rev mismatch New scripts: restore-sources.sh, provision-release.sh, verify-sources-archived.sh, check-upstream-releases.sh, validate-source-trees.py, verify-patches.sh, repair-archive-format.sh, generate-manifest.py Documentation: AGENTS.md, README.md, local/AGENTS.md updated for release fork model
This commit is contained in:
@@ -1,313 +0,0 @@
|
||||
diff --git a/drivers/hwd/src/backend/acpi.rs b/drivers/hwd/src/backend/acpi.rs
|
||||
--- a/drivers/hwd/src/backend/acpi.rs
|
||||
+++ b/drivers/hwd/src/backend/acpi.rs
|
||||
@@ -1,27 +1,36 @@
|
||||
use amlserde::{AmlSerde, AmlSerdeValue};
|
||||
-use std::{error::Error, fs, process::Command};
|
||||
+use std::{error::Error, fs};
|
||||
|
||||
use super::Backend;
|
||||
|
||||
pub struct AcpiBackend {
|
||||
- rxsdt: Vec<u8>,
|
||||
+ _rxsdt: Vec<u8>,
|
||||
}
|
||||
|
||||
impl Backend for AcpiBackend {
|
||||
fn new() -> Result<Self, Box<dyn Error>> {
|
||||
let rxsdt = fs::read("/scheme/kernel.acpi/rxsdt")?;
|
||||
|
||||
- // Spawn acpid
|
||||
- //TODO: pass rxsdt data to acpid?
|
||||
- #[allow(deprecated, reason = "we can't yet move this to init")]
|
||||
- daemon::Daemon::spawn(Command::new("acpid"));
|
||||
-
|
||||
- Ok(Self { rxsdt })
|
||||
+ Ok(Self { _rxsdt: rxsdt })
|
||||
}
|
||||
|
||||
fn probe(&mut self) -> Result<(), Box<dyn Error>> {
|
||||
+ let mut boot_critical_input_candidates = 0usize;
|
||||
+ let mut thc_candidates = 0usize;
|
||||
+ let mut non_hid_i2c_candidates = 0usize;
|
||||
+
|
||||
// Read symbols from acpi scheme
|
||||
- let entries = fs::read_dir("/scheme/acpi/symbols")?;
|
||||
+ let entries = match fs::read_dir("/scheme/acpi/symbols") {
|
||||
+ Ok(entries) => entries,
|
||||
+ Err(err)
|
||||
+ if err.kind() == std::io::ErrorKind::WouldBlock
|
||||
+ || err.raw_os_error() == Some(11) =>
|
||||
+ {
|
||||
+ log::debug!("hwd: ACPI symbols are not ready yet");
|
||||
+ return Ok(());
|
||||
+ }
|
||||
+ Err(err) => return Err(Box::new(err)),
|
||||
+ };
|
||||
// TODO: Reimplement with getdents?
|
||||
let symbols_fd = libredox::Fd::open(
|
||||
"/scheme/acpi/symbols",
|
||||
@@ -100,12 +109,103 @@
|
||||
"PNP0C0F" => "PCI interrupt link",
|
||||
"PNP0C50" => "I2C HID",
|
||||
"PNP0F13" => "PS/2 port for PS/2-style mouse",
|
||||
+ "80860F41" | "808622C1" => "DesignWare I2C controller",
|
||||
+ "AMDI0010" | "AMDI0019" | "AMDI0510" => "AMD laptop I2C controller",
|
||||
+ "INT33C2" | "INT33C3" | "INT3432" | "INT3433" | "INTC10EF" => {
|
||||
+ "Intel LPSS/SerialIO I2C controller"
|
||||
+ }
|
||||
+ "INT34C5" | "INTC1055" => "Intel GPIO controller",
|
||||
+ "INTC1050" | "INTC1051" | "INTC1080" | "INTC1081" | "INTC1082" => {
|
||||
+ "Intel THC companion (QuickI2C/QuickSPI path)"
|
||||
+ }
|
||||
+ _ if is_elan_touchpad_id(&id) => "ELAN touchpad (I2C/SMBus path)",
|
||||
+ _ if is_cypress_touchpad_id(&id) => "Cypress/Trackpad (non-HID I2C path)",
|
||||
+ _ if is_synaptics_rmi_id(&id) => "Synaptics RMI touchpad (I2C/SMBus path)",
|
||||
_ => "?",
|
||||
};
|
||||
log::debug!("{}: {} ({})", name, id, what);
|
||||
+ if is_boot_critical_i2c_surface(&id) {
|
||||
+ boot_critical_input_candidates += 1;
|
||||
+ log::info!("{}: {} is boot-critical for laptop input path", name, id);
|
||||
+ }
|
||||
+ if is_thc_companion(&id) {
|
||||
+ thc_candidates += 1;
|
||||
+ log::warn!(
|
||||
+ "{}: {} indicates Intel THC path; DMA/report fast-path is not complete yet",
|
||||
+ name,
|
||||
+ id
|
||||
+ );
|
||||
+ }
|
||||
+ if is_non_hid_i2c_input_id(&id) {
|
||||
+ non_hid_i2c_candidates += 1;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
}
|
||||
+
|
||||
+ if boot_critical_input_candidates == 0 {
|
||||
+ log::warn!(
|
||||
+ "hwd: no ACPI boot-critical I2C input candidates found; built-in laptop input may require additional controller/device support"
|
||||
+ );
|
||||
+ } else {
|
||||
+ log::info!(
|
||||
+ "hwd: ACPI input candidates: total={} thc={} non_hid_i2c={}",
|
||||
+ boot_critical_input_candidates,
|
||||
+ thc_candidates,
|
||||
+ non_hid_i2c_candidates
|
||||
+ );
|
||||
+ }
|
||||
+
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
+
|
||||
+fn is_boot_critical_i2c_surface(id: &str) -> bool {
|
||||
+ matches!(
|
||||
+ id,
|
||||
+ "PNP0C50"
|
||||
+ | "ACPI0C50"
|
||||
+ | "80860F41"
|
||||
+ | "808622C1"
|
||||
+ | "AMDI0010"
|
||||
+ | "AMDI0019"
|
||||
+ | "AMDI0510"
|
||||
+ | "INT33C2"
|
||||
+ | "INT33C3"
|
||||
+ | "INT3432"
|
||||
+ | "INT3433"
|
||||
+ | "INTC10EF"
|
||||
+ | "INT34C5"
|
||||
+ | "INTC1055"
|
||||
+ | "INTC1050"
|
||||
+ | "INTC1051"
|
||||
+ | "INTC1080"
|
||||
+ | "INTC1081"
|
||||
+ | "INTC1082"
|
||||
+ ) || is_elan_touchpad_id(id)
|
||||
+ || is_cypress_touchpad_id(id)
|
||||
+ || is_synaptics_rmi_id(id)
|
||||
+}
|
||||
+
|
||||
+fn is_thc_companion(id: &str) -> bool {
|
||||
+ matches!(
|
||||
+ id,
|
||||
+ "INTC1050" | "INTC1051" | "INTC1080" | "INTC1081" | "INTC1082"
|
||||
+ )
|
||||
+}
|
||||
+
|
||||
+fn is_elan_touchpad_id(id: &str) -> bool {
|
||||
+ id.starts_with("ELAN")
|
||||
+}
|
||||
+
|
||||
+fn is_cypress_touchpad_id(id: &str) -> bool {
|
||||
+ id.starts_with("CYAP")
|
||||
+}
|
||||
+
|
||||
+fn is_synaptics_rmi_id(id: &str) -> bool {
|
||||
+ id.starts_with("SYNA")
|
||||
+}
|
||||
+
|
||||
+fn is_non_hid_i2c_input_id(id: &str) -> bool {
|
||||
+ is_elan_touchpad_id(id) || is_cypress_touchpad_id(id) || is_synaptics_rmi_id(id)
|
||||
+}
|
||||
|
||||
diff --git a/drivers/pcid-spawner/src/main.rs b/drivers/pcid-spawner/src/main.rs
|
||||
--- a/drivers/pcid-spawner/src/main.rs
|
||||
+++ b/drivers/pcid-spawner/src/main.rs
|
||||
@@ -1,11 +1,40 @@
|
||||
+use std::env;
|
||||
use std::fs;
|
||||
use std::process::Command;
|
||||
+use std::thread;
|
||||
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
|
||||
use pcid_interface::config::Config;
|
||||
use pcid_interface::PciFunctionHandle;
|
||||
|
||||
+fn strict_usb_boot() -> bool {
|
||||
+ matches!(
|
||||
+ env::var("REDBEAR_STRICT_USB_BOOT")
|
||||
+ .ok()
|
||||
+ .as_deref()
|
||||
+ .map(str::to_ascii_lowercase)
|
||||
+ .as_deref(),
|
||||
+ Some("1" | "true" | "yes" | "on")
|
||||
+ )
|
||||
+}
|
||||
+
|
||||
+fn should_detach_in_initfs(initfs: bool, class: u8, subclass: u8, strict_usb_boot: bool) -> bool {
|
||||
+ if !initfs {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ if class == 0x01 {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ if strict_usb_boot && class == 0x0C && subclass == 0x03 {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ true
|
||||
+}
|
||||
+
|
||||
fn main() -> Result<()> {
|
||||
let mut args = pico_args::Arguments::from_env();
|
||||
let initfs = args.contains("--initfs");
|
||||
@@ -30,6 +59,7 @@
|
||||
}
|
||||
|
||||
let config: Config = toml::from_str(&config_data)?;
|
||||
+ let strict_usb_boot = strict_usb_boot();
|
||||
|
||||
for entry in fs::read_dir("/scheme/pci")? {
|
||||
let entry = entry.context("failed to get entry")?;
|
||||
@@ -87,14 +117,70 @@
|
||||
|
||||
log::info!("pcid-spawner: spawn {:?}", command);
|
||||
|
||||
+ let device_addr = handle.config().func.addr;
|
||||
+
|
||||
handle.enable_device();
|
||||
|
||||
let channel_fd = handle.into_inner_fd();
|
||||
command.env("PCID_CLIENT_CHANNEL", channel_fd.to_string());
|
||||
|
||||
#[allow(deprecated, reason = "we can't yet move this to init")]
|
||||
- daemon::Daemon::spawn(command);
|
||||
- syscall::close(channel_fd as usize).unwrap();
|
||||
+ if should_detach_in_initfs(
|
||||
+ initfs,
|
||||
+ full_device_id.class,
|
||||
+ full_device_id.subclass,
|
||||
+ strict_usb_boot,
|
||||
+ ) {
|
||||
+ log::warn!(
|
||||
+ "pcid-spawner: detached initfs spawn for {} to avoid blocking early boot",
|
||||
+ device_addr
|
||||
+ );
|
||||
+
|
||||
+ let device_addr = device_addr.to_string();
|
||||
+ thread::spawn(move || {
|
||||
+ #[allow(deprecated, reason = "we can't yet move this to init")]
|
||||
+ if let Err(err) = daemon::Daemon::spawn(command) {
|
||||
+ log::error!(
|
||||
+ "pcid-spawner: spawn/readiness failed for {}: {}",
|
||||
+ device_addr,
|
||||
+ err
|
||||
+ );
|
||||
+ log::error!(
|
||||
+ "pcid-spawner: {} remains enabled without a confirmed ready driver",
|
||||
+ device_addr
|
||||
+ );
|
||||
+ }
|
||||
+ if let Err(err) = syscall::close(channel_fd as usize) {
|
||||
+ log::error!(
|
||||
+ "pcid-spawner: failed to close channel fd {} for {}: {}",
|
||||
+ channel_fd,
|
||||
+ device_addr,
|
||||
+ err
|
||||
+ );
|
||||
+ }
|
||||
+ });
|
||||
+ } else {
|
||||
+ #[allow(deprecated, reason = "we can't yet move this to init")]
|
||||
+ if let Err(err) = daemon::Daemon::spawn(command) {
|
||||
+ log::error!(
|
||||
+ "pcid-spawner: spawn/readiness failed for {}: {}",
|
||||
+ device_addr,
|
||||
+ err
|
||||
+ );
|
||||
+ log::error!(
|
||||
+ "pcid-spawner: {} remains enabled without a confirmed ready driver",
|
||||
+ device_addr
|
||||
+ );
|
||||
+ }
|
||||
+ if let Err(err) = syscall::close(channel_fd as usize) {
|
||||
+ log::error!(
|
||||
+ "pcid-spawner: failed to close channel fd {} for {}: {}",
|
||||
+ channel_fd,
|
||||
+ device_addr,
|
||||
+ err
|
||||
+ );
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
diff --git a/drivers/pcid/src/main.rs b/drivers/pcid/src/main.rs
|
||||
--- a/drivers/pcid/src/main.rs
|
||||
+++ b/drivers/pcid/src/main.rs
|
||||
@@ -12,6 +12,7 @@
|
||||
};
|
||||
use redox_scheme::scheme::register_sync_scheme;
|
||||
use scheme_utils::Blocking;
|
||||
+use syscall::{sendfd, SendFdFlags};
|
||||
|
||||
use crate::cfg_access::Pcie;
|
||||
use pcid_interface::{FullDeviceId, LegacyInterruptLine, PciBar, PciFunction, PciRom};
|
||||
@@ -262,14 +263,13 @@
|
||||
let access_fd = socket
|
||||
.create_this_scheme_fd(0, access_id, syscall::O_RDWR, 0)
|
||||
.expect("failed to issue this resource");
|
||||
- let access_bytes = access_fd.to_ne_bytes();
|
||||
- let _ = register_pci
|
||||
- .call_wo(
|
||||
- &access_bytes,
|
||||
- syscall::CallFlags::WRITE | syscall::CallFlags::FD,
|
||||
- &[],
|
||||
- )
|
||||
- .expect("failed to send pci_fd to acpid");
|
||||
+ sendfd(
|
||||
+ register_pci.raw(),
|
||||
+ access_fd as usize,
|
||||
+ SendFdFlags::empty().bits(),
|
||||
+ 0,
|
||||
+ )
|
||||
+ .expect("failed to send pci_fd to acpid");
|
||||
}
|
||||
Err(err) => {
|
||||
if err.errno() == libredox::errno::ENODEV {
|
||||
Reference in New Issue
Block a user