Add syscall module
This commit is contained in:
parent
29b6544d8f
commit
a490ff13ae
|
@ -65,6 +65,7 @@
|
||||||
//! In this case, it is recommended to add one page, 4096 bytes, to the buffer and retry.
|
//! In this case, it is recommended to add one page, 4096 bytes, to the buffer and retry.
|
||||||
|
|
||||||
#![feature(lang_items)]
|
#![feature(lang_items)]
|
||||||
|
#![feature(question_mark)]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
@ -85,6 +86,9 @@ extern crate arch_x86_64 as arch;
|
||||||
/// Intrinsics for panic handling
|
/// Intrinsics for panic handling
|
||||||
pub mod panic;
|
pub mod panic;
|
||||||
|
|
||||||
|
/// Syscall handlers
|
||||||
|
pub mod syscall;
|
||||||
|
|
||||||
/// Tests
|
/// Tests
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub mod tests;
|
pub mod tests;
|
||||||
|
@ -93,6 +97,8 @@ pub mod tests;
|
||||||
pub extern fn kmain() {
|
pub extern fn kmain() {
|
||||||
println!("TEST");
|
println!("TEST");
|
||||||
|
|
||||||
|
println!("{:?}", syscall::open(b"file:/test/file", 0));
|
||||||
|
|
||||||
unsafe { set_interrupts() };
|
unsafe { set_interrupts() };
|
||||||
loop {
|
loop {
|
||||||
unsafe { halt() };
|
unsafe { halt() };
|
||||||
|
|
27
kernel/syscall/fs.rs
Normal file
27
kernel/syscall/fs.rs
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
//! Filesystem syscalls
|
||||||
|
|
||||||
|
use super::Result;
|
||||||
|
|
||||||
|
/// Read syscall
|
||||||
|
pub fn read(fd: usize, buf: &mut [u8]) -> Result<usize> {
|
||||||
|
println!("Read {}: {}", fd, buf.len());
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Write syscall
|
||||||
|
pub fn write(fd: usize, buf: &[u8]) -> Result<usize> {
|
||||||
|
println!("Write {}: {}", fd, buf.len());
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Open syscall
|
||||||
|
pub fn open(path: &[u8], flags: usize) -> Result<usize> {
|
||||||
|
println!("Open {:?}: {:X}", ::core::str::from_utf8(path), flags);
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Close syscall
|
||||||
|
pub fn close(fd: usize) -> Result<usize> {
|
||||||
|
println!("Close {}", fd);
|
||||||
|
Ok(0)
|
||||||
|
}
|
95
kernel/syscall/mod.rs
Normal file
95
kernel/syscall/mod.rs
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
///! Syscall handlers
|
||||||
|
|
||||||
|
use core::slice;
|
||||||
|
|
||||||
|
pub use self::fs::*;
|
||||||
|
pub use self::process::*;
|
||||||
|
|
||||||
|
/// Filesystem syscalls
|
||||||
|
pub mod fs;
|
||||||
|
|
||||||
|
/// Process syscalls
|
||||||
|
pub mod process;
|
||||||
|
|
||||||
|
/// System call list
|
||||||
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
pub enum Call {
|
||||||
|
/// Exit syscall
|
||||||
|
Exit,
|
||||||
|
/// Read syscall
|
||||||
|
Read,
|
||||||
|
/// Write syscall
|
||||||
|
Write,
|
||||||
|
/// Open syscall
|
||||||
|
Open,
|
||||||
|
/// Close syscall
|
||||||
|
Close,
|
||||||
|
/// Unknown syscall
|
||||||
|
Unknown
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convert numbers to calls
|
||||||
|
/// See http://syscalls.kernelgrok.com/
|
||||||
|
impl From<usize> for Call {
|
||||||
|
fn from(number: usize) -> Call {
|
||||||
|
match number {
|
||||||
|
1 => Call::Exit,
|
||||||
|
3 => Call::Read,
|
||||||
|
4 => Call::Write,
|
||||||
|
5 => Call::Open,
|
||||||
|
6 => Call::Close,
|
||||||
|
_ => Call::Unknown
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The error number for an invalid value
|
||||||
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
pub enum Error {
|
||||||
|
/// Operation not permitted
|
||||||
|
NotPermitted,
|
||||||
|
/// No such file or directory
|
||||||
|
NoEntry,
|
||||||
|
/// Invalid argument
|
||||||
|
InvalidValue,
|
||||||
|
/// Syscall not implemented
|
||||||
|
NoCall
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convert errors to numbers
|
||||||
|
/// See http://www-numi.fnal.gov/offline_software/srt_public_context/WebDocs/Errors/unix_system_errors.html
|
||||||
|
impl From<Error> for usize {
|
||||||
|
fn from(err: Error) -> usize {
|
||||||
|
match err {
|
||||||
|
Error::NotPermitted => 1,
|
||||||
|
Error::NoEntry => 2,
|
||||||
|
Error::InvalidValue => 22,
|
||||||
|
Error::NoCall => 38
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type Result<T> = ::core::result::Result<T, Error>;
|
||||||
|
|
||||||
|
/// Convert a pointer and length to slice, if valid
|
||||||
|
/// TODO: Check validity
|
||||||
|
pub fn convert_slice(ptr: usize, len: usize) -> Result<&'static [u8]> {
|
||||||
|
Ok(unsafe { slice::from_raw_parts(ptr as *const u8, len) })
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convert a pointer and length to slice, if valid
|
||||||
|
/// TODO: Check validity
|
||||||
|
pub fn convert_slice_mut(ptr: usize, len: usize) -> Result<&'static mut [u8]> {
|
||||||
|
Ok(unsafe { slice::from_raw_parts_mut(ptr as *mut u8, len) })
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn handle(a: usize, b: usize, c: usize, d: usize) -> ::core::result::Result<usize, usize> {
|
||||||
|
match Call::from(a) {
|
||||||
|
Call::Exit => exit(b),
|
||||||
|
Call::Read => read(b, convert_slice_mut(c, d)?),
|
||||||
|
Call::Write => write(b, convert_slice(c, d)?),
|
||||||
|
Call::Open => open(convert_slice(b, c)?, d),
|
||||||
|
Call::Close => close(b),
|
||||||
|
Call::Unknown => Err(Error::NoCall)
|
||||||
|
}.map_err(|err| err.into())
|
||||||
|
}
|
10
kernel/syscall/process.rs
Normal file
10
kernel/syscall/process.rs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
///! Process syscalls
|
||||||
|
|
||||||
|
use arch::interrupt::halt;
|
||||||
|
|
||||||
|
pub fn exit(status: usize) -> ! {
|
||||||
|
println!("Exit {}", status);
|
||||||
|
loop {
|
||||||
|
unsafe { halt() };
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue