From 951831c4bbf9d9dd44500817c79e75061a65e027 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Sun, 11 Sep 2016 16:48:58 -0600 Subject: [PATCH] Improve init process, debug missing syscalls, fix error codes in syscall return --- init/src/main.rs | 44 ++++++++++++++++++++++++++++++++++++--- kernel/lib.rs | 2 +- kernel/scheme/initfs.rs | 2 +- kernel/syscall/mod.rs | 34 +++++++++++++++++++----------- kernel/syscall/process.rs | 5 +++++ 5 files changed, 70 insertions(+), 17 deletions(-) diff --git a/init/src/main.rs b/init/src/main.rs index 899d587..093f66a 100644 --- a/init/src/main.rs +++ b/init/src/main.rs @@ -1,13 +1,51 @@ +use std::{env, thread}; use std::fs::File; use std::io::{BufRead, BufReader}; -use std::thread; +use std::process::Command; pub fn main() { let file = File::open("initfs:etc/init.rc").expect("failed to open init.rc"); let reader = BufReader::new(file); - for line in reader.lines() { - println!("{}", line.expect("failed to read init.rc")); + for line_result in reader.lines() { + let line = line_result.expect("failed to read init.rc"); + let line = line.trim(); + if ! line.is_empty() && ! line.starts_with('#') { + let mut args = line.split(' '); + if let Some(cmd) = args.next() { + match cmd { + "echo" => { + if let Some(arg) = args.next() { + print!("{}", arg); + } + for arg in args { + print!(" {}", arg); + } + print!("\n"); + }, + "cd" => if let Some(dir) = args.next() { + if let Err(err) = env::set_current_dir(dir) { + println!("init: failed to cd to '{}': {}", dir, err); + } + } else { + println!("init: failed to cd: no argument"); + }, + _ => { + let mut command = Command::new(cmd); + for arg in args { + command.arg(arg); + } + + match command.spawn() { + Ok(mut child) => if let Err(err) = child.wait() { + println!("init: failed to wait for '{}': {}", line, err); + }, + Err(err) => println!("init: failed to execute '{}': {}", line, err) + } + } + } + } + } } loop { diff --git a/kernel/lib.rs b/kernel/lib.rs index c26a057..e32d088 100644 --- a/kernel/lib.rs +++ b/kernel/lib.rs @@ -121,7 +121,7 @@ pub extern fn userspace_init() { assert_eq!(syscall::open(b"debug:", 0), Ok(1)); assert_eq!(syscall::open(b"debug:", 0), Ok(2)); - syscall::exec(b"initfs:bin/pcid", &[]).expect("failed to execute initfs:init"); + syscall::exec(b"initfs:bin/init", &[]).expect("failed to execute initfs:init"); panic!("initfs:init returned") } diff --git a/kernel/scheme/initfs.rs b/kernel/scheme/initfs.rs index cedca68..1014fe7 100644 --- a/kernel/scheme/initfs.rs +++ b/kernel/scheme/initfs.rs @@ -20,7 +20,7 @@ impl InitFsScheme { files.insert(b"bin/init", include_bytes!("../../build/userspace/init")); files.insert(b"bin/pcid", include_bytes!("../../build/userspace/pcid")); - files.insert(b"etc/init.rc", b"echo testing\n"); + files.insert(b"etc/init.rc", b"echo testing\ninitfs:bin/pcid\n"); InitFsScheme { next_id: 0, diff --git a/kernel/syscall/mod.rs b/kernel/syscall/mod.rs index 7d05149..0af4628 100644 --- a/kernel/syscall/mod.rs +++ b/kernel/syscall/mod.rs @@ -34,6 +34,8 @@ pub enum Call { Brk = 45, /// Set process I/O privilege level Iopl = 110, + /// Clone process + Clone = 120, /// Yield to scheduler SchedYield = 158 } @@ -52,6 +54,7 @@ impl Call { 20 => Ok(Call::GetPid), 45 => Ok(Call::Brk), 110 => Ok(Call::Iopl), + 120 => Ok(Call::Clone), 158 => Ok(Call::SchedYield), _ => Err(Error::NoCall) } @@ -100,17 +103,24 @@ pub fn convert_slice_mut(ptr: *mut T, len: usize) -> Result<&'static mut [T]> } pub fn handle(a: usize, b: usize, c: usize, d: usize, e: usize, _f: usize) -> Result { - match Call::from(a)? { - Call::Exit => exit(b), - Call::Read => read(b, convert_slice_mut(c as *mut u8, d)?), - Call::Write => write(b, convert_slice(c as *const u8, d)?), - Call::Open => open(convert_slice(b as *const u8, c)?, d), - Call::Close => close(b), - Call::Exec => exec(convert_slice(b as *const u8, c)?, convert_slice(d as *const [usize; 2], e)?), - Call::GetPid => getpid(), - Call::Brk => brk(b), - Call::Iopl => iopl(b), - Call::SchedYield => sched_yield() + match Call::from(a) { + Ok(call) => match call { + Call::Exit => exit(b), + Call::Read => read(b, convert_slice_mut(c as *mut u8, d)?), + Call::Write => write(b, convert_slice(c as *const u8, d)?), + Call::Open => open(convert_slice(b as *const u8, c)?, d), + Call::Close => close(b), + Call::Exec => exec(convert_slice(b as *const u8, c)?, convert_slice(d as *const [usize; 2], e)?), + Call::GetPid => getpid(), + Call::Brk => brk(b), + Call::Iopl => iopl(b), + Call::Clone => clone(b), + Call::SchedYield => sched_yield() + }, + Err(err) => { + println!("Unknown syscall {}", a); + Err(err) + } } } @@ -118,6 +128,6 @@ pub fn handle(a: usize, b: usize, c: usize, d: usize, e: usize, _f: usize) -> Re pub extern fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize) -> usize { match handle(a, b, c, d, e, f) { Ok(value) => value, - Err(value) => !(value as usize) + Err(value) => (-(value as isize)) as usize } } diff --git a/kernel/syscall/process.rs b/kernel/syscall/process.rs index 452edc2..f84be9f 100644 --- a/kernel/syscall/process.rs +++ b/kernel/syscall/process.rs @@ -61,6 +61,11 @@ pub fn brk(address: usize) -> Result { } } +pub fn clone(flags: usize) -> Result { + println!("Clone {:X}", flags); + Err(Error::NoCall) +} + pub fn exit(status: usize) -> ! { println!("Exit {}", status); loop {