From 4e270bb807522ab85dd9e77973cf102a3b086f8c Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Sun, 14 Aug 2016 18:16:56 -0600 Subject: [PATCH] Add context and file structs --- Makefile | 5 ++++- arch/test/src/interrupt.rs | 4 ++-- arch/x86_64/src/interrupt.rs | 4 ++-- kernel/context/file.rs | 10 ++++++++++ kernel/context/mod.rs | 34 ++++++++++++++++++++++++++++++++++ kernel/lib.rs | 17 +++++++++++++---- kernel/syscall/fs.rs | 18 +++++++++++++++--- kernel/syscall/mod.rs | 6 ++++++ kernel/tests/mod.rs | 4 ++-- 9 files changed, 88 insertions(+), 14 deletions(-) create mode 100644 kernel/context/file.rs create mode 100644 kernel/context/mod.rs diff --git a/Makefile b/Makefile index 284722f..4459ca8 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,10 @@ qemu: build/harddrive.bin FORCE: -build/libkernel.a: FORCE +build: + mkdir build + +build/libkernel.a: build FORCE cargo rustc -- --crate-type staticlib -o $@ #--target $(ARCH)-unknown-none.json diff --git a/arch/test/src/interrupt.rs b/arch/test/src/interrupt.rs index b167232..ffe24cc 100644 --- a/arch/test/src/interrupt.rs +++ b/arch/test/src/interrupt.rs @@ -4,14 +4,14 @@ static mut INTERRUPTS_ENABLED: bool = false; /// Clear interrupts #[inline(always)] -pub unsafe fn clear_interrupts() { +pub unsafe fn disable_interrupts() { println!("CLEAR INTERRUPTS"); INTERRUPTS_ENABLED = false; } /// Set interrupts #[inline(always)] -pub unsafe fn set_interrupts() { +pub unsafe fn enable_interrupts() { println!("SET INTERRUPTS"); INTERRUPTS_ENABLED = true; } diff --git a/arch/x86_64/src/interrupt.rs b/arch/x86_64/src/interrupt.rs index eb0bbba..9a363a3 100644 --- a/arch/x86_64/src/interrupt.rs +++ b/arch/x86_64/src/interrupt.rs @@ -2,13 +2,13 @@ /// Clear interrupts #[inline(always)] -pub unsafe fn clear_interrupts() { +pub unsafe fn disable_interrupts() { asm!("cli" : : : : "intel", "volatile"); } /// Set interrupts #[inline(always)] -pub unsafe fn set_interrupts() { +pub unsafe fn enable_interrupts() { asm!("sti" : : : : "intel", "volatile"); } diff --git a/kernel/context/file.rs b/kernel/context/file.rs new file mode 100644 index 0000000..91643ef --- /dev/null +++ b/kernel/context/file.rs @@ -0,0 +1,10 @@ +//! File struct + +/// A file +#[derive(Copy, Clone, Debug)] +pub struct File { + /// The scheme that this file refers to + pub scheme: usize, + /// The number the scheme uses to refer to this file + pub number: usize, +} diff --git a/kernel/context/mod.rs b/kernel/context/mod.rs new file mode 100644 index 0000000..8e4f37d --- /dev/null +++ b/kernel/context/mod.rs @@ -0,0 +1,34 @@ +//! Context management + +/// File operations +pub mod file; + +/// Context list +pub static mut CONTEXT: Context = Context::new(); + +/// A context, which identifies either a process or a thread +#[derive(Copy, Clone, Debug)] +pub struct Context { + /// The open files in the scheme + pub files: [Option; 32] +} + +impl Context { + pub const fn new() -> Context { + Context { + files: [None; 32] + } + } + + /// 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::File) -> Option { + for (i, mut file_option) in self.files.iter_mut().enumerate() { + if file_option.is_none() { + *file_option = Some(file); + return Some(i); + } + } + None + } +} diff --git a/kernel/lib.rs b/kernel/lib.rs index 1d0e884..929f7b3 100644 --- a/kernel/lib.rs +++ b/kernel/lib.rs @@ -64,6 +64,7 @@ //! An error will be returned, `ENOBUFS`, if the buffer is not long enough for the name. //! In this case, it is recommended to add one page, 4096 bytes, to the buffer and retry. +#![feature(const_fn)] #![feature(lang_items)] #![feature(question_mark)] #![no_std] @@ -71,7 +72,7 @@ #[macro_use] extern crate bitflags; -use arch::interrupt::{set_interrupts, halt}; +use arch::interrupt::{enable_interrupts, halt}; /// Architecture specific items (test) #[cfg(test)] @@ -83,6 +84,9 @@ extern crate arch_test as arch; #[macro_use] extern crate arch_x86_64 as arch; +/// Context management +pub mod context; + /// Intrinsics for panic handling pub mod panic; @@ -97,10 +101,15 @@ pub mod tests; pub extern fn kmain() { println!("TEST"); - println!("{:?}", syscall::open(b"file:/test/file", 0)); + println!("{:?}", syscall::open(b"stdin", 0)); + println!("{:?}", syscall::open(b"stdout", 0)); + println!("{:?}", syscall::open(b"stderr", 0)); - unsafe { set_interrupts() }; loop { - unsafe { halt() }; + unsafe { + enable_interrupts(); + halt(); + } + println!("{:?}", syscall::write(1, b"HALT\n")); } } diff --git a/kernel/syscall/fs.rs b/kernel/syscall/fs.rs index d3c6a15..1ffb91e 100644 --- a/kernel/syscall/fs.rs +++ b/kernel/syscall/fs.rs @@ -1,6 +1,6 @@ //! Filesystem syscalls -use super::Result; +use super::{Error, Result}; /// Read syscall pub fn read(fd: usize, buf: &mut [u8]) -> Result { @@ -11,13 +11,25 @@ pub fn read(fd: usize, buf: &mut [u8]) -> Result { /// Write syscall pub fn write(fd: usize, buf: &[u8]) -> Result { println!("Write {}: {}", fd, buf.len()); - Ok(0) + if let Some(file) = unsafe { &mut ::context::CONTEXT }.files.get(fd) { + println!("{:?}: {:?}", file, ::core::str::from_utf8(buf)); + Ok(buf.len()) + } else { + Err(Error::BadFile) + } } /// Open syscall pub fn open(path: &[u8], flags: usize) -> Result { println!("Open {:?}: {:X}", ::core::str::from_utf8(path), flags); - Ok(0) + if let Some(fd) = unsafe { &mut ::context::CONTEXT }.add_file(::context::file::File { + scheme: 0, + number: 0 + }) { + Ok(fd) + } else { + Err(Error::TooManyFiles) + } } /// Close syscall diff --git a/kernel/syscall/mod.rs b/kernel/syscall/mod.rs index c64caa7..5c26941 100644 --- a/kernel/syscall/mod.rs +++ b/kernel/syscall/mod.rs @@ -53,8 +53,12 @@ pub enum Error { NotPermitted, /// No such file or directory NoEntry, + /// Bad file number + BadFile, /// Invalid argument InvalidValue, + /// Too many open files + TooManyFiles, /// Syscall not implemented NoCall } @@ -66,7 +70,9 @@ impl From for usize { match err { Error::NotPermitted => 1, Error::NoEntry => 2, + Error::BadFile => 9, Error::InvalidValue => 22, + Error::TooManyFiles => 24, Error::NoCall => 38 } } diff --git a/kernel/tests/mod.rs b/kernel/tests/mod.rs index 42896c0..3603cde 100644 --- a/kernel/tests/mod.rs +++ b/kernel/tests/mod.rs @@ -1,9 +1,9 @@ -use arch::interrupt::{set_interrupts, halt}; +use arch::interrupt::{enable_interrupts, halt}; #[test] fn halt_with_interrupts() { unsafe { - set_interrupts(); + enable_interrupts(); halt(); } }