diff --git a/context/mod.rs b/context/mod.rs index 8975582..ab0ede5 100644 --- a/context/mod.rs +++ b/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/elf.rs b/elf.rs index 10be116..6a2d93f 100644 --- a/elf.rs +++ b/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/lib.rs b/lib.rs index e32d088..3943e02 100644 --- a/lib.rs +++ b/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/syscall/process.rs b/syscall/process.rs index f84be9f..18dfa89 100644 --- a/syscall/process.rs +++ b/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)