Update libstd. Add CWD and associated syscalls. Remove debugging
This commit is contained in:
parent
7561839cfc
commit
57f5699664
3
.gitmodules
vendored
3
.gitmodules
vendored
|
@ -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
|
||||
|
|
13
Makefile
13
Makefile
|
@ -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
1
ion
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit cbb3c3003f654d09cd3b3cf1a179469bb1b558b3
|
|
@ -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> {
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
2
libstd
|
@ -1 +1 @@
|
|||
Subproject commit 00920975234a9bc774ad6e33efd57a56a40c0ee8
|
||||
Subproject commit 3483097e4f5172fe8b4cbe0dee868d18201c12f8
|
|
@ -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) }
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue