Red Bear OS — microkernel OS in Rust, based on Redox

Derivative of Redox OS (https://www.redox-os.org) adding:
- AMD GPU driver (amdgpu) via LinuxKPI compat layer
- ext4 filesystem support (ext4d scheme daemon)
- ACPI fixes for AMD bare metal (x2APIC, DMAR, IVRS, MCFG)
- Custom branding (hostname, os-release, boot identity)

Build system is full upstream Redox with RBOS overlay in local/.
Patches for kernel, base, and relibc are symlinked from local/patches/
and protected from make clean/distclean. Custom recipes live in
local/recipes/ with symlinks into the recipes/ search path.

Build:  make all CONFIG_NAME=redbear-full
Sync:   ./local/scripts/sync-upstream.sh
This commit is contained in:
2026-04-12 19:05:00 +01:00
commit 50b731f1b7
3392 changed files with 98327 additions and 0 deletions
+208
View File
@@ -0,0 +1,208 @@
pub mod config;
pub mod cook;
pub mod recipe;
pub mod staged_pkg;
pub mod web;
/// Default for maximum number of levels to descend down dependencies tree.
pub const WALK_DEPTH: usize = 16;
/// Default remote package source, for recipes with build type = "remote"
pub const REMOTE_PKG_SOURCE: &str = "https://static.redox-os.org/pkg";
pub fn is_redox() -> bool {
cfg!(target_os = "redox")
}
pub fn cross_target() -> Option<String> {
std::env::var("COOKBOOK_CROSS_TARGET")
.ok()
.and_then(|s| if s.is_empty() { None } else { Some(s) })
}
// Errors
use std::fmt::Display;
use std::io;
use std::path::PathBuf;
use std::process::{Command, ExitStatus};
/// Error types used through cookbook.
///
/// When writing IO context, don't use "Failed at XXX". Look at impl Display for suitable word to use.
#[derive(Debug)]
pub enum Error {
Io {
source: io::Error,
path: Option<PathBuf>,
context: &'static str,
},
FileIo {
source: io::Error,
src: PathBuf,
dst: PathBuf,
context: &'static str,
},
Command(Command, ExitStatus),
Package(pkg::PackageError),
Pkgar(pkgar::Error),
Other(String),
}
impl Error {
pub fn from_last_io_error(context: &'static str) -> Error {
wrap_io_err!(context)(io::Error::last_os_error())
}
pub fn from_io_error(err: io::Error, context: &'static str) -> Error {
wrap_io_err!(context)(err)
}
}
impl Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Error::Io {
source,
path,
context,
} => {
if let Some(path) = path {
write!(f, "{context} failed at \"{}\": {}", path.display(), source)
} else {
write!(f, "{context} failed: {}", source)
}
}
Error::FileIo {
source,
src,
dst,
context,
} => {
write!(
f,
"{context} failed from \"{}\" to \"{}\": {}",
src.display(),
dst.display(),
source
)
}
Error::Command(command, exit_status) => {
write!(
f,
"Failed to run [{:?}]: exited with status {}",
command, exit_status
)
}
Error::Package(package_error) => write!(f, "{}", package_error),
Error::Pkgar(error) => write!(f, "{}", error),
Error::Other(context) => {
write!(f, "{context}")
}
}
}
}
macro_rules! wrap_io_err {
($context:expr) => {
|source| crate::Error::Io {
source,
path: None,
context: $context,
}
};
($path:expr, $context:expr) => {
|source| crate::Error::Io {
source,
path: Some($path.to_path_buf()),
context: $context,
}
};
($src:expr, $dst:expr, $context:expr) => {
|source| crate::Error::FileIo {
source,
src: $src.to_path_buf(),
dst: $dst.to_path_buf(),
context: $context,
}
};
}
macro_rules! wrap_other_err {
($($arg:tt)*) => {
|| crate::Error::Other(format!($($arg)*))
};
}
macro_rules! bail_other_err {
($($arg:tt)*) => {
return Err(crate::Error::Other(format!($($arg)*)))
};
}
impl From<&'static str> for Error {
fn from(value: &'static str) -> Self {
Error::Other(value.to_string())
}
}
impl From<String> for Error {
fn from(value: String) -> Self {
Error::Other(value)
}
}
impl From<Error> for String {
fn from(val: Error) -> Self {
format!("{}", val)
}
}
impl From<pkg::PackageError> for Error {
fn from(value: pkg::PackageError) -> Self {
Error::Package(value)
}
}
impl From<pkgar::Error> for Error {
fn from(value: pkgar::Error) -> Self {
match value {
pkgar::Error::Io {
source,
path,
context,
} => Error::Io {
source,
path,
context,
},
_ => Error::Pkgar(value),
}
}
}
impl From<walkdir::Error> for Error {
fn from(value: walkdir::Error) -> Self {
if value.io_error().is_some() {
let path = value.path().map(|s| s.to_path_buf());
Error::Io {
source: value.into_io_error().unwrap(),
path: path,
context: "Walkdir error",
}
} else {
wrap_other_err!(
"Walkdir file system loop found at {:?}",
value.path().map(|s| s.to_string_lossy().to_string()),
)()
}
}
}
pub type Result<T> = std::result::Result<T, Error>;
pub(crate) use wrap_io_err;
pub(crate) use wrap_other_err;
pub(crate) use bail_other_err;
pub(crate) use cook::pty::log_to_pty;