Skip to content

Commit

Permalink
Executable loading (#349)
Browse files Browse the repository at this point in the history
* Add header to binary

* Add result to spawn

* Use spawn result to display error message

* Use info result to change directory

* Fix binary detection

* Fix lock issue
  • Loading branch information
vinc authored Jun 9, 2022
1 parent 0831045 commit cd2e016
Show file tree
Hide file tree
Showing 9 changed files with 59 additions and 21 deletions.
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ export MOROS_KEYBOARD = $(keyboard)
# Build userspace binaries
user-nasm:
basename -s .s dsk/src/bin/*.s | xargs -I {} \
nasm dsk/src/bin/{}.s -o dsk/bin/{}
nasm dsk/src/bin/{}.s -o dsk/bin/{}.tmp
basename -s .s dsk/src/bin/*.s | xargs -I {} \
sh -c "printf '\x7FBIN' | cat - dsk/bin/{}.tmp > dsk/bin/{}"
rm dsk/bin/*.tmp
user-rust:
basename -s .rs src/bin/*.rs | xargs -I {} \
touch dsk/bin/{}
Expand Down
3 changes: 1 addition & 2 deletions src/api/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ use crate::api::syscall;

pub fn spawn(path: &str) -> Result<(), ()> {
if syscall::info(path).is_some() {
syscall::spawn(path);
return Ok(());
return syscall::spawn(path);
}
Err(())
}
9 changes: 7 additions & 2 deletions src/api/syscall.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,15 @@ pub fn close(handle: usize) {
unsafe { syscall!(CLOSE, handle as usize) };
}

pub fn spawn(path: &str) {
pub fn spawn(path: &str) -> Result<(), ()> {
let ptr = path.as_ptr() as usize;
let len = path.len() as usize;
unsafe { syscall!(SPAWN, ptr, len) };
let res = unsafe { syscall!(SPAWN, ptr, len) } as isize;
if res.is_negative() {
Err(())
} else {
Ok(())
}
}

pub fn reboot() {
Expand Down
1 change: 1 addition & 0 deletions src/sys/allocator.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::sys;

use alloc::slice::SliceIndex;
use alloc::sync::Arc;
use alloc::vec;
Expand Down
4 changes: 4 additions & 0 deletions src/sys/fs/dir_entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ impl FileInfo {
self.name.clone()
}

pub fn kind(&self) -> FileType {
self.kind
}

// TODO: Duplicated from dir entry
pub fn is_dir(&self) -> bool {
self.kind == FileType::Dir
Expand Down
17 changes: 12 additions & 5 deletions src/sys/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,8 @@ pub struct Registers {
pub rax: usize,
}

const ELF_MAGIC: [u8; 4] = [0x74, b'E', b'L', b'F'];
const ELF_MAGIC: [u8; 4] = [0x7F, b'E', b'L', b'F'];
const BIN_MAGIC: [u8; 4] = [0x7F, b'B', b'I', b'N'];

#[derive(Clone, Debug)]
pub struct Process {
Expand Down Expand Up @@ -242,26 +243,29 @@ impl Process {
}
}

pub fn spawn(bin: &[u8]) {
pub fn spawn(bin: &[u8]) -> Result<(), ()> {
if let Ok(pid) = Self::create(bin) {
let proc = {
let table = PROCESS_TABLE.read();
table[pid].clone()
};
proc.exec();
Ok(())
} else {
Err(())
}
}

fn create(bin: &[u8]) -> Result<usize, ()> {
// Allocate some memory for the code and the stack of the program
let code_size = 1 * PAGE_SIZE;
let code_addr = CODE_ADDR.fetch_add(code_size, Ordering::SeqCst);
sys::allocator::alloc_pages(code_addr, code_size);

let mut entry_point = 0;
let code_ptr = code_addr as *mut u8;
if bin[0..4] == ELF_MAGIC { // ELF binary
if let Ok(obj) = object::File::parse(bin) {
sys::allocator::alloc_pages(code_addr, code_size);
entry_point = obj.entry();
for segment in obj.segments() {
let addr = segment.address() as usize;
Expand All @@ -275,13 +279,16 @@ impl Process {
}
}
}
} else { // Raw binary
for (i, op) in bin.iter().enumerate() {
} else if bin[0..4] == BIN_MAGIC { // Flat binary
sys::allocator::alloc_pages(code_addr, code_size);
for (i, op) in bin.iter().skip(4).enumerate() {
unsafe {
let ptr = code_ptr.add(i);
core::ptr::write(ptr, *op);
}
}
} else {
return Err(());
}

let mut table = PROCESS_TABLE.write();
Expand Down
3 changes: 1 addition & 2 deletions src/sys/syscall/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,7 @@ pub fn dispatcher(n: usize, arg1: usize, arg2: usize, arg3: usize) -> usize {
let ptr = sys::process::ptr_from_addr(arg1 as u64);
let len = arg2;
let path = unsafe { core::str::from_utf8_unchecked(core::slice::from_raw_parts(ptr, len)) };
service::spawn(path);
0
service::spawn(path) as usize
}
number::STOP => {
service::stop(arg1)
Expand Down
5 changes: 3 additions & 2 deletions src/sys/syscall/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,9 @@ pub fn spawn(path: &str) -> isize {
let mut buf = vec![0; file.size()];
if let Ok(bytes) = file.read(&mut buf) {
buf.resize(bytes, 0);
Process::spawn(&buf);
return 0;
if Process::spawn(&buf).is_ok() {
return 0;
}
}
}
-1
Expand Down
33 changes: 26 additions & 7 deletions src/usr/shell.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
use crate::{api, sys, usr};
use crate::api::console::Style;
use crate::api::fs;
use crate::api::regex::Regex;
use crate::api::prompt::Prompt;
use crate::api::console::Style;
use crate::api::regex::Regex;
use crate::api::syscall;
use crate::sys::fs::FileType;

use alloc::collections::btree_map::BTreeMap;
use alloc::format;
Expand Down Expand Up @@ -304,11 +306,28 @@ pub fn exec(cmd: &str, env: &mut BTreeMap<String, String>) -> ExitCode {
"2048" => usr::pow::main(&args),
"time" => usr::time::main(&args),
"proc" => proc(&args),
cmd => {
if api::process::spawn(cmd).is_ok() {
ExitCode::CommandSuccessful
} else {
ExitCode::CommandUnknown
_ => {
let mut path = fs::realpath(args[0]);
if path.len() > 1 {
path = path.trim_end_matches('/').into();
}
match syscall::info(&path).map(|info| info.kind()) {
Some(FileType::Dir) => {
sys::process::set_dir(&path);
ExitCode::CommandSuccessful
}
Some(FileType::File) => {
if api::process::spawn(&path).is_ok() {
ExitCode::CommandSuccessful
} else {
error!("'{}' is not executable", path);
ExitCode::CommandError
}
}
_ => {
error!("Could not execute '{}'", cmd);
ExitCode::CommandUnknown
}
}
}
};
Expand Down

0 comments on commit cd2e016

Please sign in to comment.