From f0431f4de1bbb521154e8f07156bb55db1b40890 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Sun, 11 Sep 2016 18:03:10 -0600 Subject: [PATCH] Allow exec, emulate clone by pretending to be child --- kernel/context/mod.rs | 5 ++++- kernel/elf.rs | 8 ++++++++ kernel/lib.rs | 10 +++++++++- kernel/syscall/process.rs | 17 +++++++++-------- libstd | 2 +- syscall/src/lib.rs | 4 ++-- 6 files changed, 33 insertions(+), 13 deletions(-) diff --git a/kernel/context/mod.rs b/kernel/context/mod.rs index 8975582..ab0ede5 100644 --- a/kernel/context/mod.rs +++ b/kernel/context/mod.rs @@ -138,7 +138,7 @@ pub unsafe fn switch() { for (_pid, context_lock) in contexts().map.iter() { let mut context = context_lock.write(); - if ! context.running { + if ! context.running && ! context.blocked { to_ptr = context.deref_mut() as *mut Context; break; } @@ -165,6 +165,8 @@ pub struct Context { pub id: usize, /// Running or not pub running: bool, + /// Blocked or not + pub blocked: bool, /// The architecture specific context pub arch: ArchContext, /// Kernel stack @@ -179,6 +181,7 @@ impl Context { Context { id: id, running: false, + blocked: true, arch: ArchContext::new(), kstack: None, files: Vec::new() diff --git a/kernel/elf.rs b/kernel/elf.rs index 10be116..6a2d93f 100644 --- a/kernel/elf.rs +++ b/kernel/elf.rs @@ -60,6 +60,10 @@ impl<'a> Elf<'a> { let end_page = Page::containing_address(VirtualAddress::new((segment.p_vaddr + segment.p_memsz) as usize)); for page in Page::range_inclusive(start_page, end_page) { + if active_table.translate_page(page).is_some() { + //TODO panic!("Elf::run: still mapped: {:?}", page); + active_table.unmap(page); + } active_table.map(page, entry::NO_EXECUTE | entry::WRITABLE); } active_table.flush_all(); @@ -100,6 +104,10 @@ impl<'a> Elf<'a> { let end_page = Page::containing_address(VirtualAddress::new(0x80000000 + 64*1024 - 1)); for page in Page::range_inclusive(start_page, end_page) { + if active_table.translate_page(page).is_some() { + //TODO panic!("Elf::run: still mapped: {:?}", page); + active_table.unmap(page); + } active_table.map(page, entry::NO_EXECUTE | entry::WRITABLE | entry::USER_ACCESSIBLE); } active_table.flush_all(); diff --git a/kernel/lib.rs b/kernel/lib.rs index e32d088..3943e02 100644 --- a/kernel/lib.rs +++ b/kernel/lib.rs @@ -133,7 +133,15 @@ pub extern fn kmain() { let pid = syscall::getpid(); println!("BSP: {:?}", pid); - context::contexts_mut().spawn(userspace_init).expect("failed to spawn userspace_init"); + match context::contexts_mut().spawn(userspace_init) { + Ok(context_lock) => { + let mut context = context_lock.write(); + context.blocked = false; + }, + Err(err) => { + panic!("failed to spawn userspace_init: {:?}", err); + } + } unsafe { context::switch(); } diff --git a/kernel/syscall/process.rs b/kernel/syscall/process.rs index f84be9f..18dfa89 100644 --- a/kernel/syscall/process.rs +++ b/kernel/syscall/process.rs @@ -63,7 +63,7 @@ pub fn brk(address: usize) -> Result { pub fn clone(flags: usize) -> Result { println!("Clone {:X}", flags); - Err(Error::NoCall) + Ok(0) } pub fn exit(status: usize) -> ! { @@ -76,22 +76,23 @@ pub fn exit(status: usize) -> ! { pub fn exec(path: &[u8], _args: &[[usize; 2]]) -> Result { //TODO: Use args //TODO: Unmap previous mappings - //TODO: Drop init_data + //TODO: Drop data vec + println!("Exec {}", unsafe { str::from_utf8_unchecked(path) }); - let init_file = syscall::open(path, 0)?; - let mut init_data = vec![]; + let file = syscall::open(path, 0)?; + let mut data = vec![]; loop { let mut buf = [0; 4096]; - let count = syscall::read(init_file, &mut buf)?; + let count = syscall::read(file, &mut buf)?; if count > 0 { - init_data.extend_from_slice(&buf[..count]); + data.extend_from_slice(&buf[..count]); } else { break; } } - let _ = syscall::close(init_file); + let _ = syscall::close(file); - match elf::Elf::from(&init_data) { + match elf::Elf::from(&data) { Ok(elf) => { elf.run(); Ok(0) diff --git a/libstd b/libstd index 7b20e73..eaad8f5 160000 --- a/libstd +++ b/libstd @@ -1 +1 @@ -Subproject commit 7b20e739903a4877a10b64b875a3fd7a06cdcd16 +Subproject commit eaad8f520ce853c15c2071eff08ed813e87118fa diff --git a/syscall/src/lib.rs b/syscall/src/lib.rs index bb441de..3f3e879 100644 --- a/syscall/src/lib.rs +++ b/syscall/src/lib.rs @@ -125,8 +125,8 @@ pub fn dup(fd: usize) -> Result { unsafe { syscall1(SYS_DUP, fd) } } -pub unsafe fn execve(path: *const u8, args: *const *const u8) -> Result { - syscall2(SYS_EXECVE, path as usize, args as usize) +pub fn execve(path: &str) -> Result { + unsafe { syscall2(SYS_EXECVE, path.as_ptr() as usize, path.len()) } } pub fn exit(status: usize) -> Result {