Add fsync. Add env scheme, currently hardcoded to get ion to launch. Make serial IRQ send data to debug scheme
This commit is contained in:
parent
1b056395bb
commit
483d466b1a
|
@ -102,7 +102,12 @@ impl SerialPort {
|
|||
|
||||
pub fn on_receive(&mut self) {
|
||||
let data = self.data.read();
|
||||
self.write_translate(data);
|
||||
|
||||
extern {
|
||||
fn debug_input(byte: u8);
|
||||
}
|
||||
|
||||
unsafe { debug_input(data) };
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,25 @@
|
|||
use collections::VecDeque;
|
||||
use core::str;
|
||||
use spin::{Mutex, MutexGuard, Once};
|
||||
|
||||
use context;
|
||||
use syscall::Result;
|
||||
use super::Scheme;
|
||||
|
||||
/// Input
|
||||
static INPUT: Once<Mutex<VecDeque<u8>>> = Once::new();
|
||||
|
||||
/// Initialize contexts, called if needed
|
||||
fn init_input() -> Mutex<VecDeque<u8>> {
|
||||
Mutex::new(VecDeque::new())
|
||||
}
|
||||
|
||||
/// Get the global schemes list, const
|
||||
#[no_mangle]
|
||||
pub extern fn debug_input(b: u8) {
|
||||
INPUT.call_once(init_input).lock().push_back(b)
|
||||
}
|
||||
|
||||
pub struct DebugScheme;
|
||||
|
||||
impl Scheme for DebugScheme {
|
||||
|
@ -17,8 +34,23 @@ impl Scheme for DebugScheme {
|
|||
/// Read the file `number` into the `buffer`
|
||||
///
|
||||
/// Returns the number of bytes read
|
||||
fn read(&mut self, _file: usize, _buffer: &mut [u8]) -> Result<usize> {
|
||||
Ok(0)
|
||||
fn read(&mut self, _file: usize, buf: &mut [u8]) -> Result<usize> {
|
||||
loop {
|
||||
let mut i = 0;
|
||||
{
|
||||
let mut input = INPUT.call_once(init_input).lock();
|
||||
while i < buf.len() && ! input.is_empty() {
|
||||
buf[i] = input.pop_front().expect("debug_input lost byte");
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if i > 0 {
|
||||
return Ok(i);
|
||||
} else {
|
||||
unsafe { context::switch(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Write the `buffer` to the `file`
|
||||
|
@ -30,6 +62,10 @@ impl Scheme for DebugScheme {
|
|||
Ok(buffer.len())
|
||||
}
|
||||
|
||||
fn fsync(&mut self, file: usize) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Close the file `number`
|
||||
fn close(&mut self, _file: usize) -> Result<()> {
|
||||
Ok(())
|
||||
|
|
88
kernel/scheme/env.rs
Normal file
88
kernel/scheme/env.rs
Normal file
|
@ -0,0 +1,88 @@
|
|||
use collections::BTreeMap;
|
||||
|
||||
use syscall::{Error, Result};
|
||||
use super::Scheme;
|
||||
|
||||
struct Handle {
|
||||
data: &'static [u8],
|
||||
seek: usize
|
||||
}
|
||||
|
||||
pub struct EnvScheme {
|
||||
next_id: usize,
|
||||
files: BTreeMap<&'static [u8], &'static [u8]>,
|
||||
handles: BTreeMap<usize, Handle>
|
||||
}
|
||||
|
||||
impl EnvScheme {
|
||||
pub fn new() -> EnvScheme {
|
||||
let mut files: BTreeMap<&'static [u8], &'static [u8]> = BTreeMap::new();
|
||||
|
||||
files.insert(b"HOME", b"initfs:");
|
||||
files.insert(b"PWD", b"initfs:");
|
||||
files.insert(b"COLUMNS", b"80");
|
||||
files.insert(b"LINES", b"30");
|
||||
|
||||
EnvScheme {
|
||||
next_id: 0,
|
||||
files: files,
|
||||
handles: BTreeMap::new()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Scheme for EnvScheme {
|
||||
fn open(&mut self, path: &[u8], _flags: usize) -> Result<usize> {
|
||||
let data = self.files.get(path).ok_or(Error::NoEntry)?;
|
||||
|
||||
let id = self.next_id;
|
||||
self.next_id += 1;
|
||||
self.handles.insert(id, Handle {
|
||||
data: data,
|
||||
seek: 0
|
||||
});
|
||||
|
||||
Ok(id)
|
||||
}
|
||||
|
||||
fn dup(&mut self, file: usize) -> Result<usize> {
|
||||
let (data, seek) = {
|
||||
let handle = self.handles.get(&file).ok_or(Error::BadFile)?;
|
||||
(handle.data, handle.seek)
|
||||
};
|
||||
|
||||
let id = self.next_id;
|
||||
self.next_id += 1;
|
||||
self.handles.insert(id, Handle {
|
||||
data: data,
|
||||
seek: seek
|
||||
});
|
||||
|
||||
Ok(id)
|
||||
}
|
||||
|
||||
fn read(&mut self, file: usize, buffer: &mut [u8]) -> Result<usize> {
|
||||
let mut handle = self.handles.get_mut(&file).ok_or(Error::BadFile)?;
|
||||
|
||||
let mut i = 0;
|
||||
while i < buffer.len() && handle.seek < handle.data.len() {
|
||||
buffer[i] = handle.data[handle.seek];
|
||||
i += 1;
|
||||
handle.seek += 1;
|
||||
}
|
||||
|
||||
Ok(i)
|
||||
}
|
||||
|
||||
fn write(&mut self, _file: usize, _buffer: &[u8]) -> Result<usize> {
|
||||
Err(Error::NotPermitted)
|
||||
}
|
||||
|
||||
fn fsync(&mut self, file: usize) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn close(&mut self, file: usize) -> Result<()> {
|
||||
self.handles.remove(&file).ok_or(Error::BadFile).and(Ok(()))
|
||||
}
|
||||
}
|
|
@ -78,6 +78,10 @@ impl Scheme for InitFsScheme {
|
|||
Err(Error::NotPermitted)
|
||||
}
|
||||
|
||||
fn fsync(&mut self, file: usize) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn close(&mut self, file: usize) -> Result<()> {
|
||||
self.handles.remove(&file).ok_or(Error::BadFile).and(Ok(()))
|
||||
}
|
||||
|
|
|
@ -16,11 +16,15 @@ use spin::{Once, Mutex, RwLock, RwLockReadGuard, RwLockWriteGuard};
|
|||
use syscall::{Error, Result};
|
||||
|
||||
use self::debug::DebugScheme;
|
||||
use self::env::EnvScheme;
|
||||
use self::initfs::InitFsScheme;
|
||||
|
||||
/// Debug scheme
|
||||
pub mod debug;
|
||||
|
||||
/// Environmental variables
|
||||
pub mod env;
|
||||
|
||||
/// InitFS scheme
|
||||
pub mod initfs;
|
||||
|
||||
|
@ -57,7 +61,7 @@ impl SchemeList {
|
|||
}
|
||||
}
|
||||
|
||||
/// Create a new context.
|
||||
/// Create a new scheme.
|
||||
pub fn insert(&mut self, name: Box<[u8]>, scheme: Arc<Mutex<Box<Scheme + Send>>>) -> Result<&Arc<Mutex<Box<Scheme + Send>>>> {
|
||||
if self.names.contains_key(&name) {
|
||||
return Err(Error::FileExists);
|
||||
|
@ -92,6 +96,7 @@ static SCHEMES: Once<RwLock<SchemeList>> = Once::new();
|
|||
fn init_schemes() -> RwLock<SchemeList> {
|
||||
let mut list: SchemeList = SchemeList::new();
|
||||
list.insert(Box::new(*b"debug"), Arc::new(Mutex::new(Box::new(DebugScheme)))).expect("failed to insert debug: scheme");
|
||||
list.insert(Box::new(*b"env"), Arc::new(Mutex::new(Box::new(EnvScheme::new())))).expect("failed to insert env: scheme");
|
||||
list.insert(Box::new(*b"initfs"), Arc::new(Mutex::new(Box::new(InitFsScheme::new())))).expect("failed to insert initfs: scheme");
|
||||
RwLock::new(list)
|
||||
}
|
||||
|
@ -128,6 +133,9 @@ pub trait Scheme {
|
|||
/// Returns the number of bytes written
|
||||
fn write(&mut self, file: usize, buffer: &[u8]) -> Result<usize>;
|
||||
|
||||
/// Sync the file descriptor
|
||||
fn fsync(&mut self, file: usize) -> Result<()>;
|
||||
|
||||
/// Close the file descriptor
|
||||
fn close(&mut self, file: usize) -> Result<()>;
|
||||
}
|
||||
|
|
|
@ -29,6 +29,8 @@ pub enum Call {
|
|||
Brk = 45,
|
||||
/// Set process I/O privilege level
|
||||
Iopl = 110,
|
||||
/// Sync file descriptor
|
||||
FSync = 118,
|
||||
/// Clone process
|
||||
Clone = 120,
|
||||
/// Yield to scheduler
|
||||
|
@ -55,6 +57,7 @@ impl Call {
|
|||
41 => Ok(Call::Dup),
|
||||
45 => Ok(Call::Brk),
|
||||
110 => Ok(Call::Iopl),
|
||||
118 => Ok(Call::FSync),
|
||||
120 => Ok(Call::Clone),
|
||||
158 => Ok(Call::SchedYield),
|
||||
183 => Ok(Call::GetCwd),
|
||||
|
|
|
@ -120,3 +120,18 @@ pub fn dup(fd: usize) -> Result<usize> {
|
|||
let result = scheme_mutex.lock().dup(file.number);
|
||||
result
|
||||
}
|
||||
|
||||
pub fn fsync(fd: usize) -> Result<usize> {
|
||||
let file = {
|
||||
let contexts = context::contexts();
|
||||
let context_lock = contexts.current().ok_or(Error::NoProcess)?;
|
||||
let context = context_lock.read();
|
||||
let file = context.get_file(fd).ok_or(Error::BadFile)?;
|
||||
file
|
||||
};
|
||||
|
||||
let schemes = scheme::schemes();
|
||||
let scheme_mutex = schemes.get(file.scheme).ok_or(Error::BadFile)?;
|
||||
let result = scheme_mutex.lock().fsync(file.number).and(Ok(0));
|
||||
result
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ pub extern fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize
|
|||
Call::Dup => dup(b),
|
||||
Call::Brk => brk(b),
|
||||
Call::Iopl => iopl(b),
|
||||
Call::FSync => fsync(b),
|
||||
Call::Clone => clone(b, stack),
|
||||
Call::SchedYield => sched_yield(),
|
||||
Call::GetCwd => getcwd(validate_slice_mut(b as *mut u8, c)?)
|
||||
|
|
Loading…
Reference in a new issue