Commit 23f4c76e authored by Jeremy Soller's avatar Jeremy Soller

Fixes for launching init

parent 30e68f91
......@@ -137,6 +137,7 @@ static mut INIT_ENV: &[u8] = &[];
/// Initialize userspace by running the initfs:bin/init process
/// This function will also set the CWD to initfs:bin and open debug: as stdio
pub extern fn userspace_init() {
let path = b"/bin/init";
let env = unsafe { INIT_ENV };
assert_eq!(syscall::chdir(b"initfs:"), Ok(0));
......@@ -145,17 +146,17 @@ pub extern fn userspace_init() {
assert_eq!(syscall::open(b"debug:", syscall::flag::O_WRONLY).map(FileHandle::into), Ok(1));
assert_eq!(syscall::open(b"debug:", syscall::flag::O_WRONLY).map(FileHandle::into), Ok(2));
let fd = syscall::open(b"/bin/init", syscall::flag::O_RDONLY).expect("failed to open init");
let fd = syscall::open(path, syscall::flag::O_RDONLY).expect("failed to open init");
let mut env_ptrs = Vec::new();
for line in env.split(|b| *b == b'\n') {
env_ptrs.push([
line.as_ptr() as usize,
line.len(),
]);
let mut args = Vec::new();
args.push(path.to_vec().into_boxed_slice());
let mut vars = Vec::new();
for var in env.split(|b| *b == b'\n') {
vars.push(var.to_vec().into_boxed_slice());
}
syscall::fexec(fd, &[], &env_ptrs).expect("failed to execute init");
syscall::fexec_kernel(fd, args.into_boxed_slice(), vars.into_boxed_slice()).expect("failed to execute init");
panic!("init returned");
}
......@@ -164,6 +165,7 @@ pub extern fn userspace_init() {
pub fn kmain(cpus: usize, env: &'static [u8]) -> ! {
CPU_ID.store(0, Ordering::SeqCst);
CPU_COUNT.store(cpus, Ordering::SeqCst);
unsafe { INIT_ENV = env };
//Initialize the first context, stored in kernel/src/context/mod.rs
context::init();
......@@ -172,7 +174,6 @@ pub fn kmain(cpus: usize, env: &'static [u8]) -> ! {
println!("BSP: {:?} {}", pid, cpus);
println!("Env: {:?}", ::core::str::from_utf8(env));
unsafe { INIT_ENV = env };
match context::contexts_mut().spawn(userspace_init) {
Ok(context_lock) => {
let mut context = context_lock.write();
......
......@@ -527,7 +527,7 @@ impl Drop for ExecFile {
}
}
fn exec_noreturn(
fn fexec_noreturn(
setuid: Option<u32>,
setgid: Option<u32>,
data: Box<[u8]>,
......@@ -765,21 +765,7 @@ fn exec_noreturn(
unsafe { usermode(entry, sp, 0); }
}
pub fn fexec(fd: FileHandle, arg_ptrs: &[[usize; 2]], var_ptrs: &[[usize; 2]]) -> Result<usize> {
let mut args = Vec::new();
for arg_ptr in arg_ptrs {
let arg = validate_slice(arg_ptr[0] as *const u8, arg_ptr[1])?;
// Argument must be moved into kernel space before exec unmaps all memory
args.push(arg.to_vec().into_boxed_slice());
}
let mut vars = Vec::new();
for var_ptr in var_ptrs {
let var = validate_slice(var_ptr[0] as *const u8, var_ptr[1])?;
// Argument must be moved into kernel space before exec unmaps all memory
vars.push(var.to_vec().into_boxed_slice());
}
pub fn fexec_kernel(fd: FileHandle, args: Box<[Box<[u8]>]>, vars: Box<[Box<[u8]>]>) -> Result<usize> {
let (uid, gid) = {
let contexts = context::contexts();
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
......@@ -899,14 +885,30 @@ pub fn fexec(fd: FileHandle, arg_ptrs: &[[usize; 2]], var_ptrs: &[[usize; 2]]) -
}
}
// Drop so that usage is not allowed after unmapping context
drop(arg_ptrs);
drop(var_ptrs);
// This is the point of no return, quite literaly. Any checks for validity need
// to be done before, and appropriate errors returned. Otherwise, we have nothing
// to return to.
exec_noreturn(setuid, setgid, data.into_boxed_slice(), args.into_boxed_slice(), vars.into_boxed_slice());
fexec_noreturn(setuid, setgid, data.into_boxed_slice(), args, vars);
}
pub fn fexec(fd: FileHandle, arg_ptrs: &[[usize; 2]], var_ptrs: &[[usize; 2]]) -> Result<usize> {
let mut args = Vec::new();
for arg_ptr in arg_ptrs {
let arg = validate_slice(arg_ptr[0] as *const u8, arg_ptr[1])?;
// Argument must be moved into kernel space before exec unmaps all memory
args.push(arg.to_vec().into_boxed_slice());
}
drop(arg_ptrs);
let mut vars = Vec::new();
for var_ptr in var_ptrs {
let var = validate_slice(var_ptr[0] as *const u8, var_ptr[1])?;
// Argument must be moved into kernel space before exec unmaps all memory
vars.push(var.to_vec().into_boxed_slice());
}
drop(var_ptrs);
fexec_kernel(fd, args.into_boxed_slice(), vars.into_boxed_slice())
}
pub fn exit(status: usize) -> ! {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment