Update libstd. Add CWD and associated syscalls. Remove debugging

This commit is contained in:
Jeremy Soller 2016-09-17 19:01:34 -06:00
parent 7561839cfc
commit 57f5699664
12 changed files with 113 additions and 12 deletions

3
.gitmodules vendored
View file

@ -7,3 +7,6 @@
[submodule "ralloc"]
path = ralloc
url = https://github.com/redox-os/ralloc
[submodule "ion"]
path = ion
url = https://github.com/redox-os/ion.git

View file

@ -12,9 +12,9 @@ KCARGOFLAGS=--target $(KTARGET).json -- -C soft-float
TARGET=$(ARCH)-unknown-redox
BUILD=build/userspace
RUSTC=./rustc.sh
RUSTCFLAGS=--target $(TARGET).json -O -C soft-float --cfg redox
RUSTCFLAGS=--target $(TARGET).json -C soft-float --cfg redox
CARGO=RUSTC="$(RUSTC)" cargo
CARGOFLAGS=--target $(TARGET).json -- -O -C soft-float --cfg redox
CARGOFLAGS=--target $(TARGET).json -- -C soft-float --cfg redox
# Default targets
.PHONY: all clean qemu bochs FORCE
@ -25,6 +25,7 @@ clean:
cargo clean
cargo clean --manifest-path libstd/Cargo.toml
cargo clean --manifest-path init/Cargo.toml
cargo clean --manifest-path ion/Cargo.toml
cargo clean --manifest-path drivers/pcid/Cargo.toml
rm -rf build
@ -93,7 +94,7 @@ $(KBUILD)/librustc_unicode.rlib: rust/src/librustc_unicode/lib.rs $(KBUILD)/libc
$(KBUILD)/libcollections.rlib: rust/src/libcollections/lib.rs $(KBUILD)/libcore.rlib $(KBUILD)/liballoc.rlib $(KBUILD)/librustc_unicode.rlib
$(KRUSTC) $(KRUSTCFLAGS) -o $@ $<
$(KBUILD)/libkernel.a: kernel/** $(KBUILD)/libcore.rlib $(KBUILD)/liballoc.rlib $(KBUILD)/libcollections.rlib $(BUILD)/init $(BUILD)/pcid FORCE
$(KBUILD)/libkernel.a: kernel/** $(KBUILD)/libcore.rlib $(KBUILD)/liballoc.rlib $(KBUILD)/libcollections.rlib $(BUILD)/initfs.rs FORCE
$(KCARGO) rustc $(KCARGOFLAGS) -o $@
$(KBUILD)/kernel: $(KBUILD)/libkernel.a
@ -124,6 +125,12 @@ $(BUILD)/init: init/Cargo.toml init/src/*.rs $(BUILD)/libstd.rlib
$(CARGO) rustc --manifest-path $< $(CARGOFLAGS) -o $@
strip $@
$(BUILD)/ion: ion/Cargo.toml ion/src/*.rs $(BUILD)/libstd.rlib
$(CARGO) rustc --manifest-path $< $(CARGOFLAGS) -o $@
strip $@
$(BUILD)/pcid: drivers/pcid/Cargo.toml drivers/pcid/src/** $(BUILD)/libstd.rlib
$(CARGO) rustc --manifest-path $< $(CARGOFLAGS) -o $@
strip $@
$(BUILD)/initfs.rs: $(BUILD)/init $(BUILD)/ion $(BUILD)/pcid

1
ion Submodule

@ -0,0 +1 @@
Subproject commit cbb3c3003f654d09cd3b3cf1a179469bb1b558b3

View file

@ -33,6 +33,8 @@ pub struct Context {
pub heap: Option<SharedMemory>,
/// User stack
pub stack: Option<Memory>,
/// The current working directory
pub cwd: Arc<Mutex<Vec<u8>>>,
/// The open files in the scheme
pub files: Arc<Mutex<Vec<Option<File>>>>
}
@ -49,10 +51,46 @@ impl Context {
image: Vec::new(),
heap: None,
stack: None,
cwd: Arc::new(Mutex::new(Vec::new())),
files: Arc::new(Mutex::new(Vec::new()))
}
}
pub fn canonicalize(&self, path: &[u8]) -> Vec<u8> {
if path.iter().position(|&b| b == b':').is_none() {
let cwd = self.cwd.lock();
if path == b"." {
cwd.clone()
} else if path == b".." {
cwd[..cwd[..cwd.len() - 1]
.iter().rposition(|&b| b == b'/')
.map_or(cwd.len(), |i| i + 1)]
.to_vec()
} else if path.starts_with(b"./") {
let mut canon = cwd.clone();
canon.extend_from_slice(&path[2..]);
canon
} else if path.starts_with(b"../") {
let mut canon = cwd[..cwd[..cwd.len() - 1]
.iter().rposition(|&b| b == b'/')
.map_or(cwd.len(), |i| i + 1)]
.to_vec();
canon.extend_from_slice(&path[3..]);
canon
} else if path.starts_with(b"/") {
let mut canon = cwd[..cwd.iter().position(|&b| b == b':').map_or(1, |i| i + 1)].to_vec();
canon.extend_from_slice(&path);
canon
} else {
let mut canon = cwd.clone();
canon.extend_from_slice(&path);
canon
}
} else {
path.to_vec()
}
}
/// Add a file to the lowest available slot.
/// Return the file descriptor number or None if no slot was found
pub fn add_file(&mut self, file: File) -> Option<usize> {

View file

@ -128,6 +128,8 @@ pub fn cpu_id() -> usize {
}
pub extern fn userspace_init() {
assert_eq!(syscall::chdir(b"initfs:"), Ok(0));
assert_eq!(syscall::open(b"debug:", 0), Ok(0));
assert_eq!(syscall::open(b"debug:", 0), Ok(1));
assert_eq!(syscall::open(b"debug:", 0), Ok(2));

View file

@ -19,8 +19,9 @@ impl InitFsScheme {
let mut files: BTreeMap<&'static [u8], &'static [u8]> = BTreeMap::new();
files.insert(b"bin/init", include_bytes!("../../build/userspace/init"));
files.insert(b"bin/ion", include_bytes!("../../build/userspace/ion"));
files.insert(b"bin/pcid", include_bytes!("../../build/userspace/pcid"));
files.insert(b"etc/init.rc", b"echo testing\ninitfs:bin/pcid\n");
files.insert(b"etc/init.rc", b"echo testing\ninitfs:bin/pcid\ninitfs:bin/ion");
InitFsScheme {
next_id: 0,

View file

@ -19,6 +19,8 @@ pub enum Call {
WaitPid = 7,
/// Execute syscall
Exec = 11,
/// Change working directory
ChDir = 12,
/// Get process ID
GetPid = 20,
/// Duplicate file descriptor
@ -30,12 +32,15 @@ pub enum Call {
/// Clone process
Clone = 120,
/// Yield to scheduler
SchedYield = 158
SchedYield = 158,
/// Get process working directory
GetCwd = 183
}
/// Convert numbers to calls
/// See http://syscalls.kernelgrok.com/
impl Call {
//TODO: Return Option<Call>
pub fn from(number: usize) -> Result<Call> {
match number {
1 => Ok(Call::Exit),
@ -45,12 +50,14 @@ impl Call {
6 => Ok(Call::Close),
7 => Ok(Call::WaitPid),
11 => Ok(Call::Exec),
12 => Ok(Call::ChDir),
20 => Ok(Call::GetPid),
41 => Ok(Call::Dup),
45 => Ok(Call::Brk),
110 => Ok(Call::Iopl),
120 => Ok(Call::Clone),
158 => Ok(Call::SchedYield),
183 => Ok(Call::GetCwd),
_ => Err(Error::NoCall)
}
}

View file

@ -5,6 +5,28 @@ use scheme;
use super::{Error, Result};
pub fn chdir(path: &[u8]) -> Result<usize> {
let contexts = context::contexts();
let context_lock = contexts.current().ok_or(Error::NoProcess)?;
let context = context_lock.read();
let canonical = context.canonicalize(path);
*context.cwd.lock() = canonical;
Ok(0)
}
pub fn getcwd(buf: &mut [u8]) -> Result<usize> {
let contexts = context::contexts();
let context_lock = contexts.current().ok_or(Error::NoProcess)?;
let context = context_lock.read();
let cwd = context.cwd.lock();
let mut i = 0;
while i < buf.len() && i < cwd.len() {
buf[i] = cwd[i];
i += 1;
}
Ok(i)
}
/// Read syscall
pub fn read(fd: usize, buf: &mut [u8]) -> Result<usize> {
let file = {

View file

@ -34,12 +34,14 @@ pub extern fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize
Call::Close => close(b),
Call::WaitPid => waitpid(b, c, d),
Call::Exec => exec(validate_slice(b as *const u8, c)?, validate_slice(d as *const [usize; 2], e)?),
Call::ChDir => chdir(validate_slice(b as *const u8, c)?),
Call::GetPid => getpid(),
Call::Dup => dup(b),
Call::Brk => brk(b),
Call::Iopl => iopl(b),
Call::Clone => clone(b, stack),
Call::SchedYield => sched_yield()
Call::SchedYield => sched_yield(),
Call::GetCwd => getcwd(validate_slice_mut(b as *mut u8, c)?)
},
Err(err) => {
println!("Unknown syscall {}", a);

View file

@ -1,6 +1,7 @@
///! Process syscalls
use alloc::arc::Arc;
use collections::Vec;
use core::mem;
use core::str;
use spin::Mutex;
@ -53,7 +54,9 @@ pub const CLONE_FILES: usize = 0x400;
pub const CLONE_VFORK: usize = 0x4000;
pub fn clone(flags: usize, stack_base: usize) -> Result<usize> {
//TODO: Copy on write?
println!("Clone {:X}: {:X}", flags, stack_base);
// vfork not supported
assert!(flags & CLONE_VFORK == 0);
let ppid;
let pid;
@ -64,7 +67,8 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<usize> {
let mut image = vec![];
let mut heap_option = None;
let mut stack_option = None;
let mut files = Arc::new(Mutex::new(vec![]));
let cwd;
let files;
// Copy from old process
{
@ -159,9 +163,16 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<usize> {
stack_option = Some(new_stack);
}
if flags & CLONE_FS == CLONE_FS {
cwd = context.cwd.clone();
} else {
cwd = Arc::new(Mutex::new(context.cwd.lock().clone()));
}
if flags & CLONE_FILES == CLONE_FILES {
files = context.files.clone();
} else {
let mut files_vec = Vec::new();
for (fd, file_option) in context.files.lock().iter().enumerate() {
if let Some(file) = *file_option {
let result = {
@ -172,16 +183,17 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<usize> {
};
match result {
Ok(new_number) => {
files.lock().push(Some(context::file::File { scheme: file.scheme, number: new_number }));
files_vec.push(Some(context::file::File { scheme: file.scheme, number: new_number }));
},
Err(err) => {
println!("clone: failed to dup {}: {:?}", fd, err);
}
}
} else {
files.lock().push(None);
files_vec.push(None);
}
}
files = Arc::new(Mutex::new(files_vec));
}
}
@ -289,6 +301,8 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<usize> {
context.stack = Some(stack);
}
context.cwd = cwd;
context.files = files;
context.arch.set_page_table(unsafe { new_table.address() });
@ -322,7 +336,6 @@ pub fn exec(path: &[u8], _args: &[[usize; 2]]) -> Result<usize> {
//TODO: Use args
//TODO: Unmap previous mappings
//TODO: Drop data vec
println!("Exec {}", unsafe { str::from_utf8_unchecked(path) });
let file = syscall::open(path, 0)?;
let mut data = vec![];

2
libstd

@ -1 +1 @@
Subproject commit 00920975234a9bc774ad6e33efd57a56a40c0ee8
Subproject commit 3483097e4f5172fe8b4cbe0dee868d18201c12f8

View file

@ -48,6 +48,7 @@ pub const SYS_FUTEX: usize = 240;
pub const FUTEX_WAIT: usize = 0;
pub const FUTEX_WAKE: usize = 1;
pub const FUTEX_REQUEUE: usize = 2;
pub const SYS_GETCWD: usize = 183;
pub const SYS_GETPID: usize = 20;
pub const SYS_IOPL: usize = 110;
pub const SYS_LINK: usize = 9;
@ -153,6 +154,10 @@ pub unsafe fn futex(addr: *mut i32, op: usize, val: i32, val2: usize, addr2: *mu
syscall5(SYS_FUTEX, addr as usize, op, (val as isize) as usize, val2, addr2 as usize)
}
pub fn getcwd(buf: &mut [u8]) -> Result<usize> {
unsafe { syscall2(SYS_GETCWD, buf.as_mut_ptr() as usize, buf.len()) }
}
pub fn getpid() -> Result<usize> {
unsafe { syscall0(SYS_GETPID) }
}