Improve init process, debug missing syscalls, fix error codes in syscall return
This commit is contained in:
parent
adec5d6df6
commit
951831c4bb
|
@ -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 {
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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<T>(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<usize> {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,6 +61,11 @@ pub fn brk(address: usize) -> Result<usize> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn clone(flags: usize) -> Result<usize> {
|
||||
println!("Clone {:X}", flags);
|
||||
Err(Error::NoCall)
|
||||
}
|
||||
|
||||
pub fn exit(status: usize) -> ! {
|
||||
println!("Exit {}", status);
|
||||
loop {
|
||||
|
|
Loading…
Reference in a new issue