diff --git a/Cargo.lock b/Cargo.lock index 756eb376f2..da3013f8a6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -441,6 +441,10 @@ dependencies = [ "redox_syscall 0.7.1", ] +[[package]] +name = "config" +version = "0.0.0" + [[package]] name = "console-draw" version = "0.1.0" @@ -1098,6 +1102,7 @@ dependencies = [ name = "init" version = "0.1.0" dependencies = [ + "config", "daemon", "libredox", ] @@ -1480,6 +1485,7 @@ version = "0.1.0" dependencies = [ "anyhow", "common", + "config", "daemon", "log", "pcid", diff --git a/Cargo.toml b/Cargo.toml index f087b5a050..3bc2d91d4d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,6 +2,7 @@ resolver = "2" members = [ "audiod", + "config", "daemon", "init", "initfs", diff --git a/aarch64-unknown-redox/init_drivers.rc b/aarch64-unknown-redox/init_drivers.rc deleted file mode 100644 index f5985bebfe..0000000000 --- a/aarch64-unknown-redox/init_drivers.rc +++ /dev/null @@ -1,2 +0,0 @@ -notify hwd -pcid-spawner /scheme/initfs/etc/pcid/initfs.toml diff --git a/aarch64-unknown-redox/init_drivers.rc.raspi3bp b/aarch64-unknown-redox/init_drivers.rc.raspi3bp deleted file mode 100644 index 2534ef0727..0000000000 --- a/aarch64-unknown-redox/init_drivers.rc.raspi3bp +++ /dev/null @@ -1 +0,0 @@ -notify bcm2835-sdhcid diff --git a/config/Cargo.toml b/config/Cargo.toml new file mode 100644 index 0000000000..4bad20a8ef --- /dev/null +++ b/config/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "config" +version = "0.0.0" +edition = "2024" + +[dependencies] diff --git a/config/src/lib.rs b/config/src/lib.rs new file mode 100644 index 0000000000..e7ba434d23 --- /dev/null +++ b/config/src/lib.rs @@ -0,0 +1,40 @@ +use std::collections::BTreeMap; +use std::path::{Path, PathBuf}; +use std::{fs, io}; + +pub fn config(name: &str) -> Result, io::Error> { + config_for_dirs(&[ + &Path::new("/usr/lib").join(format!("{name}.d")), + &Path::new("/etc").join(format!("{name}.d")), + ]) +} + +pub fn config_for_initfs(name: &str) -> Result, io::Error> { + config_for_dirs(&[ + &Path::new("/scheme/initfs/lib").join(format!("{name}.d")), + &Path::new("/scheme/initfs/etc").join(format!("{name}.d")), + ]) +} + +pub fn config_for_dirs(dirs: &[impl AsRef]) -> Result, io::Error> { + // This must be a BTreeMap to iterate in sorted order. + let mut entries = BTreeMap::new(); + + for dir in dirs { + let dir = dir.as_ref(); + if !dir.exists() { + // Skip non-existent dirs + continue; + } + + for entry_res in fs::read_dir(&dir)? { + // This intentionally overwrites older entries with + // the same filename to allow overriding entries in + // one search dir with those in a later search dir. + let entry = entry_res?; + entries.insert(entry.file_name(), entry.path()); + } + } + + Ok(entries.into_values().collect()) +} diff --git a/drivers/pcid-spawner/Cargo.toml b/drivers/pcid-spawner/Cargo.toml index 3f25a546db..b9ded7001b 100644 --- a/drivers/pcid-spawner/Cargo.toml +++ b/drivers/pcid-spawner/Cargo.toml @@ -13,6 +13,7 @@ redox_syscall.workspace = true serde = { version = "1", features = ["derive"] } toml = "0.5" +config = { path = "../../config" } common = { path = "../common" } daemon = { path = "../../daemon" } pcid = { path = "../pcid" } diff --git a/drivers/pcid-spawner/src/main.rs b/drivers/pcid-spawner/src/main.rs index 74019c4425..fca15b5865 100644 --- a/drivers/pcid-spawner/src/main.rs +++ b/drivers/pcid-spawner/src/main.rs @@ -8,9 +8,7 @@ use pcid_interface::PciFunctionHandle; fn main() -> Result<()> { let mut args = pico_args::Arguments::from_env(); - let config_path = args - .free_from_str::() - .expect("failed to parse --config argument"); + let initfs = args.contains("--initfs"); common::setup_logging( "bus", @@ -20,17 +18,17 @@ fn main() -> Result<()> { common::file_level(), ); - let config_data = if fs::metadata(&config_path)?.is_file() { - fs::read_to_string(&config_path)? + let mut config_data = String::new(); + for path in if initfs { + config::config_for_initfs("pcid")? } else { - let mut config_data = String::new(); - for path in fs::read_dir(&config_path)? { - if let Ok(tmp) = fs::read_to_string(path.unwrap().path()) { - config_data.push_str(&tmp); - } + config::config("pcid")? + } { + if let Ok(tmp) = fs::read_to_string(path) { + config_data.push_str(&tmp); } - config_data - }; + } + let config: Config = toml::from_str(&config_data)?; for entry in fs::read_dir("/scheme/pci")? { diff --git a/init.d.aarch64-unknown-redox/40_drivers b/init.d.aarch64-unknown-redox/40_drivers new file mode 100644 index 0000000000..fcfa633d87 --- /dev/null +++ b/init.d.aarch64-unknown-redox/40_drivers @@ -0,0 +1,3 @@ +notify hwd +unset RSDP_ADDR RSDP_SIZE +pcid-spawner --initfs diff --git a/init.d.aarch64-unknown-redox/40_drivers.raspi3bp b/init.d.aarch64-unknown-redox/40_drivers.raspi3bp new file mode 100644 index 0000000000..ce5444645a --- /dev/null +++ b/init.d.aarch64-unknown-redox/40_drivers.raspi3bp @@ -0,0 +1,2 @@ +unset RSDP_ADDR RSDP_SIZE +notify bcm2835-sdhcid diff --git a/init.d/00_runtime b/init.d/00_runtime new file mode 100644 index 0000000000..6f4f3da3b2 --- /dev/null +++ b/init.d/00_runtime @@ -0,0 +1,8 @@ +# Various daemons that relibc needs to function as well as a bunch of env vars +# that should be set for every program. +export PATH /scheme/initfs/bin +export RUST_BACKTRACE 1 +rtcd +notify nulld +notify zerod +notify randd diff --git a/init.d/10_logging b/init.d/10_logging new file mode 100644 index 0000000000..63a23fc339 --- /dev/null +++ b/init.d/10_logging @@ -0,0 +1,3 @@ +notify logd +stdio /scheme/log +notify ramfs logging diff --git a/init.d/20_graphics b/init.d/20_graphics new file mode 100644 index 0000000000..a286364179 --- /dev/null +++ b/init.d/20_graphics @@ -0,0 +1,8 @@ +notify inputd +notify vesad +unset FRAMEBUFFER_ADDR FRAMEBUFFER_VIRT FRAMEBUFFER_WIDTH FRAMEBUFFER_HEIGHT FRAMEBUFFER_STRIDE +#TODO: unset FRAMEBUFFER1 and beyond? +notify fbbootlogd +# Activate framebuffer log VT, which disables kernel graphical debug +inputd -A 1 +notify fbcond 2 diff --git a/init.d/30_live b/init.d/30_live new file mode 100644 index 0000000000..a5db207150 --- /dev/null +++ b/init.d/30_live @@ -0,0 +1,2 @@ +# Note: Needs to start before drivers to ensure it gets priority when redoxfs searches for disks +notify lived diff --git a/init.d/40_drivers b/init.d/40_drivers new file mode 100644 index 0000000000..8f3fa01e71 --- /dev/null +++ b/init.d/40_drivers @@ -0,0 +1,4 @@ +notify ps2d +notify hwd +unset RSDP_ADDR RSDP_SIZE +pcid-spawner --initfs diff --git a/init.d/50_rootfs b/init.d/50_rootfs new file mode 100644 index 0000000000..9102f1fa6d --- /dev/null +++ b/init.d/50_rootfs @@ -0,0 +1,2 @@ +redoxfs --uuid $REDOXFS_UUID file $REDOXFS_BLOCK +unset REDOXFS_UUID REDOXFS_BLOCK REDOXFS_PASSWORD_ADDR REDOXFS_PASSWORD_SIZE diff --git a/init.d/90_exit_initfs b/init.d/90_exit_initfs new file mode 100644 index 0000000000..c52fff54e9 --- /dev/null +++ b/init.d/90_exit_initfs @@ -0,0 +1,4 @@ +cd / +export PATH /usr/bin +unset LD_LIBRARY_PATH +run.d /usr/lib/init.d /etc/init.d diff --git a/init.rc b/init.rc deleted file mode 100644 index ee2e111281..0000000000 --- a/init.rc +++ /dev/null @@ -1,41 +0,0 @@ -# Various daemons that relibc needs to function as well as a bunch of env vars -# that should be set for every program. -export PATH /scheme/initfs/bin -export RUST_BACKTRACE 1 -rtcd -notify nulld -notify zerod -notify randd - -# Logging -notify logd -stdio /scheme/log -notify ramfs logging - -# Graphics infrastructure -notify inputd -notify vesad -unset FRAMEBUFFER_ADDR FRAMEBUFFER_VIRT FRAMEBUFFER_WIDTH FRAMEBUFFER_HEIGHT FRAMEBUFFER_STRIDE -#TODO: unset FRAMEBUFFER1 and beyond? -notify fbbootlogd -# Activate framebuffer log VT, which disables kernel graphical debug -inputd -A 1 -notify fbcond 2 - -# Live disk -# Note: Needs to start before drivers to ensure it gets priority when redoxfs searches for disks -notify lived - -# Drivers -run /scheme/initfs/etc/init_drivers.rc -unset RSDP_ADDR RSDP_SIZE - -# Mount rootfs -redoxfs --uuid $REDOXFS_UUID file $REDOXFS_BLOCK -unset REDOXFS_UUID REDOXFS_BLOCK REDOXFS_PASSWORD_ADDR REDOXFS_PASSWORD_SIZE - -# Exit initfs -cd / -export PATH /usr/bin -unset LD_LIBRARY_PATH -run.d /usr/lib/init.d /etc/init.d diff --git a/init/Cargo.toml b/init/Cargo.toml index d82425bc60..e97eb1673f 100644 --- a/init/Cargo.toml +++ b/init/Cargo.toml @@ -7,4 +7,5 @@ license = "MIT" [dependencies] libredox.workspace = true +config = { path = "../config" } daemon = { path = "../daemon" } diff --git a/init/src/main.rs b/init/src/main.rs index dca3ba9382..d0c133e30e 100644 --- a/init/src/main.rs +++ b/init/src/main.rs @@ -1,7 +1,5 @@ -use std::collections::BTreeMap; -use std::fs::read_dir; use std::io::Result; -use std::path::Path; +use std::path::{Path, PathBuf}; use std::process::Command; use std::{env, fs}; @@ -103,46 +101,20 @@ fn run_command(line: &str, config: &InitConfig) { } } "run.d" => { - // This must be a BTreeMap to iterate in sorted order. - let mut entries = BTreeMap::new(); - let mut missing_arg = true; - - for new_dir in args { - if !Path::new(&new_dir).exists() { - // Skip non-existent dirs - continue; - } - missing_arg = false; - - let list = match read_dir(&new_dir) { - Ok(list) => list, - Err(err) => { - eprintln!("init: failed to run.d: '{}': {}", new_dir, err); - continue; - } - }; - for entry_res in list { - match entry_res { - Ok(entry) => { - // This intentionally overwrites older entries with - // the same filename to allow overriding entries in - // one search dir with those in a later search dir. - entries.insert(entry.file_name(), entry.path()); - } - Err(err) => { - eprintln!("init: failed to run.d: '{}': {}", new_dir, err); - } - } - } - } - - if missing_arg { + let args = args.map(|arg| PathBuf::from(arg)).collect::>(); + if args.is_empty() { eprintln!("init: failed to run.d: no argument or all dirs are non-existent"); return; } + let entries = match config::config_for_dirs(&args) { + Ok(list) => list, + Err(err) => { + eprintln!("init: failed to run.d: '{args:?}': {err}"); + return; + } + }; - // This takes advantage of BTreeMap iterating in sorted order. - for (_, entry_path) in entries { + for entry_path in entries { if let Err(err) = run(&entry_path, config) { eprintln!("init: failed to run '{}': {}", entry_path.display(), err); } @@ -234,10 +206,18 @@ fn run_command(line: &str, config: &InitConfig) { } fn main() { - let init_path = Path::new("/scheme/initfs/etc/init.rc"); let init_config = InitConfig::new(); - if let Err(err) = run(&init_path, &init_config) { - eprintln!("init: failed to run {:?}: {}", init_path, err); + let entries = match config::config_for_initfs("init") { + Ok(entries) => entries, + Err(err) => { + eprintln!("init: failed to find config files: {}", err); + return; + } + }; + for entry_path in entries { + if let Err(err) = run(&entry_path, &init_config) { + eprintln!("init: failed to run '{}': {}", entry_path.display(), err); + } } libredox::call::setrens(0, 0).expect("init: failed to enter null namespace"); diff --git a/init_drivers.rc b/init_drivers.rc deleted file mode 100644 index f69f919da9..0000000000 --- a/init_drivers.rc +++ /dev/null @@ -1,3 +0,0 @@ -notify ps2d -notify hwd -pcid-spawner /scheme/initfs/etc/pcid/initfs.toml