vfs: move operations into trait StorageDevice, hold StorageDevices in KERNEL_STATE
This commit is contained in:
parent
9462350de7
commit
31a3feb6a0
|
@ -6,4 +6,21 @@
|
||||||
|
|
||||||
pub enum FsError {
|
pub enum FsError {
|
||||||
UnsupportedOperation,
|
UnsupportedOperation,
|
||||||
|
InvalidDevice,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Into<FsError> for ext2::error::Error {
|
||||||
|
fn into(self) -> FsError {
|
||||||
|
match self {
|
||||||
|
ext2::error::Error::Other(_) => todo!(),
|
||||||
|
ext2::error::Error::BadMagic { magic: _ } => todo!(),
|
||||||
|
ext2::error::Error::OutOfBounds { index: _ } => todo!(),
|
||||||
|
ext2::error::Error::AddressOutOfBounds { sector: _, offset: _, size: _ } => todo!(),
|
||||||
|
ext2::error::Error::BadBlockGroupCount { by_blocks: _, by_inodes: _ } => todo!(),
|
||||||
|
ext2::error::Error::InodeNotFound { inode: _ } => todo!(),
|
||||||
|
ext2::error::Error::NotADirectory { inode: _, name: _ } => todo!(),
|
||||||
|
ext2::error::Error::NotAbsolute { name: _ } => todo!(),
|
||||||
|
ext2::error::Error::NotFound { name: _ } => todo!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
85
ableos/src/filesystem/ext2.rs
Normal file
85
ableos/src/filesystem/ext2.rs
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
use ext2::fs::Ext2;
|
||||||
|
use ext2::sector::SectorSize;
|
||||||
|
use ext2::volume::Volume;
|
||||||
|
|
||||||
|
use super::{FsResult as Result, StorageDevice};
|
||||||
|
|
||||||
|
pub struct Ext2StorageDevice<S, V>
|
||||||
|
where
|
||||||
|
S: SectorSize,
|
||||||
|
V: Volume<u8, S>,
|
||||||
|
{
|
||||||
|
fs: Ext2<S, V>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S, V> Ext2StorageDevice<S, V>
|
||||||
|
where
|
||||||
|
S: SectorSize,
|
||||||
|
V: Volume<u8, S>,
|
||||||
|
{
|
||||||
|
pub fn new(volume: V) -> Result<Self> {
|
||||||
|
Ok(Self {
|
||||||
|
fs: Ext2::new(volume).map_err(|e| e.into())?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S, V> StorageDevice for Ext2StorageDevice<S, V>
|
||||||
|
where
|
||||||
|
S: SectorSize + Send,
|
||||||
|
V: Volume<u8, S> + Send,
|
||||||
|
{
|
||||||
|
fn open(&self, node: &super::FsNode /* TODO: flags */) -> Result<crate::handle::Handle> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn close(&self, node: &super::FsNode) -> Result<()> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read(&self, node: &super::FsNode, offset: u32, size: u32) -> Result<Box<[u8]>> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write(&self, node: &super::FsNode, offset: u32, buffer: Box<[u8]>) -> Result<()> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_dir(&self, node: &super::FsNode, index: u32) -> Result<super::DirectoryEntry> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn find_dir(&self, node: &super::FsNode, name: &str) -> Result<super::FsNode> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// fn load_fs() -> Arc<Mutex<Ext2<Size1024, Vec<u8>>>> {
|
||||||
|
// let mut volume = Vec::new();
|
||||||
|
// volume.extend_from_slice(include_bytes!("../../../userland/root_fs/ext2.img"));
|
||||||
|
|
||||||
|
// Arc::<Ext2<Size1024, _>>::new(volume).unwrap()
|
||||||
|
// }
|
||||||
|
|
||||||
|
// pub fn walk<S: SectorSize, V: Volume<u8, S>>(
|
||||||
|
// fs: &Synced<Ext2<S, V>>,
|
||||||
|
// inode: Inode<S, V>,
|
||||||
|
// name: String,
|
||||||
|
// ) {
|
||||||
|
// if let Some(dir) = inode.directory() {
|
||||||
|
// for entry in dir {
|
||||||
|
// assert!(entry.is_ok());
|
||||||
|
// let entry = entry.unwrap();
|
||||||
|
// let entry_name = String::from_utf8_lossy(&entry.name);
|
||||||
|
|
||||||
|
// println!("{}/{} => {}", name, entry_name, entry.inode,);
|
||||||
|
// if entry_name != "." && entry_name != ".." {
|
||||||
|
// walk(
|
||||||
|
// fs,
|
||||||
|
// fs.inode_nth(entry.inode).unwrap(),
|
||||||
|
// format!("{}/{}", name, entry_name),
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
|
@ -5,34 +5,29 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
pub mod errors;
|
pub mod errors;
|
||||||
|
pub mod ext2;
|
||||||
|
|
||||||
use alloc::rc::Weak;
|
use alloc::rc::Weak;
|
||||||
use bitflags::bitflags;
|
use bitflags::bitflags;
|
||||||
use ext2::{
|
|
||||||
fs::{
|
|
||||||
sync::{Inode, Synced},
|
|
||||||
Ext2,
|
|
||||||
},
|
|
||||||
sector::{SectorSize, Size1024},
|
|
||||||
volume::Volume,
|
|
||||||
};
|
|
||||||
use spin::Lazy;
|
|
||||||
|
|
||||||
use crate::handle::Handle;
|
use crate::{handle::Handle, KERNEL_STATE};
|
||||||
|
|
||||||
use self::errors::FsError;
|
use self::errors::FsError;
|
||||||
use FsResult as Result;
|
use FsResult as Result;
|
||||||
|
|
||||||
pub type FsResult<T> = core::result::Result<T, FsError>;
|
pub type FsResult<T> = core::result::Result<T, FsError>;
|
||||||
|
|
||||||
pub type FsOpenOperation = fn(node: &FsNode /* TODO: flags */) -> Result<Handle>;
|
pub trait StorageDevice
|
||||||
pub type FsCloseOperation = fn(node: &FsNode) -> Result<()>;
|
where
|
||||||
pub type FsReadOperation = fn(node: &FsNode, offset: u32, size: u32)
|
Self: Send,
|
||||||
-> Result<Box<[u8]>>;
|
{
|
||||||
pub type FsWriteOperation = fn(node: &FsNode, offset: u32, buffer: Box<[u8]>)
|
fn open(&self, node: &FsNode /* TODO: flags */) -> Result<Handle>;
|
||||||
-> Result<()>;
|
fn close(&self, node: &FsNode) -> Result<()>;
|
||||||
pub type FsReaddirOperation = fn(node: &FsNode, index: u32) -> Result<DirectoryEntry>;
|
fn read(&self, node: &FsNode, offset: u32, size: u32) -> Result<Box<[u8]>>;
|
||||||
pub type FsFinddirOperation = fn(node: &FsNode, name: &str) -> Result<FsNode>;
|
fn write(&self, node: &FsNode, offset: u32, buffer: Box<[u8]>) -> Result<()>;
|
||||||
|
fn read_dir(&self, node: &FsNode, index: u32) -> Result<DirectoryEntry>;
|
||||||
|
fn find_dir(&self, node: &FsNode, name: &str) -> Result<FsNode>;
|
||||||
|
}
|
||||||
|
|
||||||
/// A VFS node, that can either be a file or a directory.
|
/// A VFS node, that can either be a file or a directory.
|
||||||
pub struct FsNode {
|
pub struct FsNode {
|
||||||
|
@ -44,12 +39,6 @@ pub struct FsNode {
|
||||||
inode: u32, // implementation specific identifier for the node
|
inode: u32, // implementation specific identifier for the node
|
||||||
device_handle: Handle, // uniquely assigned device handle
|
device_handle: Handle, // uniquely assigned device handle
|
||||||
ptr: Weak<FsNode>, // used by mountpoints and symlinks
|
ptr: Weak<FsNode>, // used by mountpoints and symlinks
|
||||||
open: Option<FsOpenOperation>,
|
|
||||||
close: Option<FsCloseOperation>,
|
|
||||||
read: Option<FsReadOperation>,
|
|
||||||
write: Option<FsWriteOperation>,
|
|
||||||
readdir: Option<FsReaddirOperation>,
|
|
||||||
finddir: Option<FsFinddirOperation>,
|
|
||||||
// todo: permissions mask
|
// todo: permissions mask
|
||||||
// todo: owning user/group
|
// todo: owning user/group
|
||||||
}
|
}
|
||||||
|
@ -57,51 +46,57 @@ pub struct FsNode {
|
||||||
impl FsNode {
|
impl FsNode {
|
||||||
// TODO: make this take flags
|
// TODO: make this take flags
|
||||||
fn open(&self) -> Result<Handle> {
|
fn open(&self) -> Result<Handle> {
|
||||||
if let Some(open) = self.open {
|
let state = KERNEL_STATE.lock();
|
||||||
open(self)
|
let device = state
|
||||||
} else {
|
.get_storage_device(self.device_handle)
|
||||||
Err(FsError::UnsupportedOperation)
|
.ok_or_else(|| FsError::InvalidDevice)?;
|
||||||
}
|
|
||||||
|
device.open(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn close(&self) -> Result<()> {
|
fn close(&self) -> Result<()> {
|
||||||
if let Some(close) = self.close {
|
let state = KERNEL_STATE.lock();
|
||||||
close(self)
|
let device = state
|
||||||
} else {
|
.get_storage_device(self.device_handle)
|
||||||
Err(FsError::UnsupportedOperation)
|
.ok_or_else(|| FsError::InvalidDevice)?;
|
||||||
}
|
|
||||||
|
device.close(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read(&self, offset: u32, size: u32) -> Result<Box<[u8]>> {
|
fn read(&self, offset: u32, size: u32) -> Result<Box<[u8]>> {
|
||||||
if let Some(read) = self.read {
|
let state = KERNEL_STATE.lock();
|
||||||
read(self, offset, size)
|
let device = state
|
||||||
} else {
|
.get_storage_device(self.device_handle)
|
||||||
Err(FsError::UnsupportedOperation)
|
.ok_or_else(|| FsError::InvalidDevice)?;
|
||||||
}
|
|
||||||
|
device.read(self, offset, size)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write(&self, offset: u32, buffer: Box<[u8]>) -> Result<()> {
|
fn write(&self, offset: u32, buffer: Box<[u8]>) -> Result<()> {
|
||||||
if let Some(write) = self.write {
|
let state = KERNEL_STATE.lock();
|
||||||
write(self, offset, buffer)
|
let device = state
|
||||||
} else {
|
.get_storage_device(self.device_handle)
|
||||||
Err(FsError::UnsupportedOperation)
|
.ok_or_else(|| FsError::InvalidDevice)?;
|
||||||
}
|
|
||||||
|
device.write(self, offset, buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn readdir(&self, index: u32) -> Result<DirectoryEntry> {
|
fn read_dir(&self, index: u32) -> Result<DirectoryEntry> {
|
||||||
if let Some(readdir) = self.readdir {
|
let state = KERNEL_STATE.lock();
|
||||||
readdir(self, index)
|
let device = state
|
||||||
} else {
|
.get_storage_device(self.device_handle)
|
||||||
Err(FsError::UnsupportedOperation)
|
.ok_or_else(|| FsError::InvalidDevice)?;
|
||||||
}
|
|
||||||
|
device.read_dir(self, index)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn finddir(&self, name: &str) -> Result<FsNode> {
|
fn find_dir(&self, name: &str) -> Result<FsNode> {
|
||||||
if let Some(finddir) = self.finddir {
|
let state = KERNEL_STATE.lock();
|
||||||
finddir(self, name)
|
let device = state
|
||||||
} else {
|
.get_storage_device(self.device_handle)
|
||||||
Err(FsError::UnsupportedOperation)
|
.ok_or_else(|| FsError::InvalidDevice)?;
|
||||||
}
|
|
||||||
|
device.find_dir(self, name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,36 +119,3 @@ pub struct DirectoryEntry {
|
||||||
name: String,
|
name: String,
|
||||||
inode: u32,
|
inode: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub static FILE_SYSTEM: Lazy<spin::Mutex<Synced<Ext2<Size1024, Vec<u8>>>>> =
|
|
||||||
Lazy::new(|| spin::Mutex::new(load_fs()));
|
|
||||||
|
|
||||||
pub fn walk<S: SectorSize, V: Volume<u8, S>>(
|
|
||||||
fs: &Synced<Ext2<S, V>>,
|
|
||||||
inode: Inode<S, V>,
|
|
||||||
name: String,
|
|
||||||
) {
|
|
||||||
if let Some(dir) = inode.directory() {
|
|
||||||
for entry in dir {
|
|
||||||
assert!(entry.is_ok());
|
|
||||||
let entry = entry.unwrap();
|
|
||||||
let entry_name = String::from_utf8_lossy(&entry.name);
|
|
||||||
|
|
||||||
println!("{}/{} => {}", name, entry_name, entry.inode,);
|
|
||||||
if entry_name != "." && entry_name != ".." {
|
|
||||||
walk(
|
|
||||||
fs,
|
|
||||||
fs.inode_nth(entry.inode).unwrap(),
|
|
||||||
format!("{}/{}", name, entry_name),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn load_fs() -> Synced<Ext2<Size1024, Vec<u8>>> {
|
|
||||||
let mut volume = Vec::new();
|
|
||||||
volume.extend_from_slice(include_bytes!("../../../userland/root_fs/ext2.img"));
|
|
||||||
|
|
||||||
Synced::<Ext2<Size1024, _>>::new(volume).unwrap()
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,10 +1,14 @@
|
||||||
|
use hashbrown::HashMap;
|
||||||
use spin::Lazy;
|
use spin::Lazy;
|
||||||
|
|
||||||
|
use crate::{handle::{Handle, HandleResource}, filesystem::StorageDevice};
|
||||||
|
|
||||||
pub static KERNEL_STATE: Lazy<spin::Mutex<KernelInternalState>> =
|
pub static KERNEL_STATE: Lazy<spin::Mutex<KernelInternalState>> =
|
||||||
Lazy::new(|| spin::Mutex::new(KernelInternalState::new()));
|
Lazy::new(|| spin::Mutex::new(KernelInternalState::new()));
|
||||||
|
|
||||||
pub struct KernelInternalState {
|
pub struct KernelInternalState {
|
||||||
pub hostname: String,
|
pub hostname: String,
|
||||||
|
storage_devices: HashMap<Handle, Box<dyn StorageDevice>>,
|
||||||
should_shutdown: bool,
|
should_shutdown: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,6 +16,7 @@ impl KernelInternalState {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
should_shutdown: false,
|
should_shutdown: false,
|
||||||
|
storage_devices: HashMap::new(),
|
||||||
hostname: "".to_string(),
|
hostname: "".to_string(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,9 +24,19 @@ impl KernelInternalState {
|
||||||
pub fn set_hostname(&mut self, hostname: String) {
|
pub fn set_hostname(&mut self, hostname: String) {
|
||||||
self.hostname = hostname;
|
self.hostname = hostname;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn add_storage_device(&mut self, device: impl StorageDevice + Send + 'static) {
|
||||||
|
self.storage_devices.insert(Handle::new(HandleResource::StorageDevice), Box::new(device));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_storage_device(&self, handle: Handle) -> Option<&dyn StorageDevice> {
|
||||||
|
self.storage_devices.get(&handle).map(|d| &**d)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn shutdown(&mut self) {
|
pub fn shutdown(&mut self) {
|
||||||
self.should_shutdown = true;
|
self.should_shutdown = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_state(&mut self) {
|
pub fn update_state(&mut self) {
|
||||||
if self.should_shutdown {
|
if self.should_shutdown {
|
||||||
crate::arch::shutdown();
|
crate::arch::shutdown();
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::arch::drivers::sysinfo::master;
|
use crate::arch::drivers::sysinfo::master;
|
||||||
use crate::systeminfo::{KERNEL_VERSION, RELEASE_TYPE};
|
use crate::systeminfo::{KERNEL_VERSION, RELEASE_TYPE};
|
||||||
use crate::{filesystem::FILE_SYSTEM, time::fetch_time, KERNEL_STATE};
|
use crate::{time::fetch_time, KERNEL_STATE};
|
||||||
use genfs::{Fs, OpenOptions};
|
// use genfs::{Fs, OpenOptions};
|
||||||
use kernel::allocator::ALLOCATOR;
|
use kernel::allocator::ALLOCATOR;
|
||||||
// use rhai::Engine;
|
// use rhai::Engine;
|
||||||
use spin::Lazy;
|
use spin::Lazy;
|
||||||
|
@ -103,23 +103,23 @@ pub fn poke_memory(ptr: i64, val: i64) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ls() {
|
// pub fn ls() {
|
||||||
let current_dir = CURRENT_DIR.lock();
|
// let current_dir = CURRENT_DIR.lock();
|
||||||
|
|
||||||
let fs = &*FILE_SYSTEM.lock();
|
// let fs = &*FILE_SYSTEM.lock();
|
||||||
|
|
||||||
let file = fs
|
// let file = fs
|
||||||
.open(current_dir.as_bytes(), OpenOptions::new().read(true))
|
// .open(current_dir.as_bytes(), OpenOptions::new().read(true))
|
||||||
.unwrap();
|
// .unwrap();
|
||||||
|
|
||||||
let mut files = file.directory().unwrap();
|
// let mut files = file.directory().unwrap();
|
||||||
println!("current dir: {}", *current_dir);
|
// println!("current dir: {}", *current_dir);
|
||||||
while let Some(Ok(entry)) = files.next() {
|
// while let Some(Ok(entry)) = files.next() {
|
||||||
let inode_name = entry.name;
|
// let inode_name = entry.name;
|
||||||
let s = String::from_utf8_lossy(&inode_name);
|
// let s = String::from_utf8_lossy(&inode_name);
|
||||||
println!("{}", s);
|
// println!("{}", s);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub fn log_dump() {
|
pub fn log_dump() {
|
||||||
use crate::network::socket::SimpleSock;
|
use crate::network::socket::SimpleSock;
|
||||||
|
@ -144,55 +144,55 @@ pub fn log_dump() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn echo_file(path: String) {
|
// pub fn echo_file(path: String) {
|
||||||
let mut current_dir = CURRENT_DIR.lock();
|
// let mut current_dir = CURRENT_DIR.lock();
|
||||||
|
|
||||||
let fs = &*FILE_SYSTEM.lock();
|
// let fs = &*FILE_SYSTEM.lock();
|
||||||
|
|
||||||
current_dir.push_str(&path);
|
// current_dir.push_str(&path);
|
||||||
|
|
||||||
let file = fs
|
// let file = fs
|
||||||
.open(current_dir.as_bytes(), OpenOptions::new().read(true))
|
// .open(current_dir.as_bytes(), OpenOptions::new().read(true))
|
||||||
.unwrap();
|
// .unwrap();
|
||||||
|
|
||||||
if file.is_dir() {
|
// if file.is_dir() {
|
||||||
println!("{} is a directory", path);
|
// println!("{} is a directory", path);
|
||||||
} else {
|
// } else {
|
||||||
let mut file_contents = Vec::new();
|
// let mut file_contents = Vec::new();
|
||||||
|
|
||||||
let _ret = file.read_to_end(&mut file_contents).unwrap();
|
// let _ret = file.read_to_end(&mut file_contents).unwrap();
|
||||||
|
|
||||||
let file_contents_str = String::from_utf8_lossy(&file_contents);
|
// let file_contents_str = String::from_utf8_lossy(&file_contents);
|
||||||
|
|
||||||
println!("{}", file_contents_str);
|
// println!("{}", file_contents_str);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub fn change_directory(path: String) {
|
// pub fn change_directory(path: String) {
|
||||||
let mut current_dir = CURRENT_DIR.lock();
|
// let mut current_dir = CURRENT_DIR.lock();
|
||||||
|
|
||||||
let _fs = &*FILE_SYSTEM.lock();
|
// let _fs = &*FILE_SYSTEM.lock();
|
||||||
if path == "." || path == ".." {
|
// if path == "." || path == ".." {
|
||||||
let mut split_dir = current_dir.split('/').collect::<Vec<&str>>();
|
// let mut split_dir = current_dir.split('/').collect::<Vec<&str>>();
|
||||||
let mut new_dir = String::new();
|
// let mut new_dir = String::new();
|
||||||
split_dir.remove(split_dir.len() - 1);
|
// split_dir.remove(split_dir.len() - 1);
|
||||||
println!("{:?}", split_dir);
|
// println!("{:?}", split_dir);
|
||||||
if split_dir.is_empty() {
|
// if split_dir.is_empty() {
|
||||||
new_dir = "/".to_string();
|
// new_dir = "/".to_string();
|
||||||
} else {
|
// } else {
|
||||||
for x in split_dir {
|
// for x in split_dir {
|
||||||
new_dir.push_str(x);
|
// new_dir.push_str(x);
|
||||||
new_dir.push('/');
|
// new_dir.push('/');
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
*current_dir = new_dir;
|
// *current_dir = new_dir;
|
||||||
} else {
|
// } else {
|
||||||
if !current_dir.ends_with('/') {
|
// if !current_dir.ends_with('/') {
|
||||||
current_dir.push('/');
|
// current_dir.push('/');
|
||||||
}
|
// }
|
||||||
current_dir.push_str(&path);
|
// current_dir.push_str(&path);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
// fn engine_construction() -> Engine {
|
// fn engine_construction() -> Engine {
|
||||||
// let mut engine = rhai::Engine::new();
|
// let mut engine = rhai::Engine::new();
|
||||||
|
|
|
@ -11,8 +11,8 @@ use crate::systeminfo::{KERNEL_VERSION, RELEASE_TYPE};
|
||||||
use crate::time::fetch_time;
|
use crate::time::fetch_time;
|
||||||
use crate::KERNEL_STATE;
|
use crate::KERNEL_STATE;
|
||||||
use crate::{
|
use crate::{
|
||||||
arch::shutdown, filesystem::FILE_SYSTEM, rhai_shell::KEYBUFF, vterm::VTerm,
|
arch::shutdown, rhai_shell::KEYBUFF, vterm::Term,
|
||||||
wasm_jumploader::run_program,
|
// wasm_jumploader::run_program,
|
||||||
};
|
};
|
||||||
|
|
||||||
use acpi::{AcpiTables, PlatformInfo};
|
use acpi::{AcpiTables, PlatformInfo};
|
||||||
|
@ -193,7 +193,7 @@ pub fn real_shell() {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn command_parser(user: String, command: String) {
|
pub fn command_parser(user: String, command: String) {
|
||||||
let fs = &*FILE_SYSTEM.lock();
|
// let fs = &*FILE_SYSTEM.lock();
|
||||||
let mut iter = command.split_whitespace();
|
let mut iter = command.split_whitespace();
|
||||||
|
|
||||||
// TODO: update the open() function to take either a ableOS path or a b"/" type path
|
// TODO: update the open() function to take either a ableOS path or a b"/" type path
|
||||||
|
@ -225,41 +225,48 @@ pub fn command_parser(user: String, command: String) {
|
||||||
// drop(fs);
|
// drop(fs);
|
||||||
// shell();
|
// shell();
|
||||||
// }
|
// }
|
||||||
"list" | "ls" => {
|
// "list" | "ls" => {
|
||||||
for dir_entry in list_files_in_dir(fs, current_path) {
|
// for dir_entry in list_files_in_dir(fs, current_path) {
|
||||||
println!("{}", dir_entry.file_name_string());
|
// println!("{}", dir_entry.file_name_string());
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
"echo" => match conf_args.1.arguments.get("p") {
|
"echo" => match conf_args.1.arguments.get("p") {
|
||||||
Some(path) => echo_file(path.to_string(), fs),
|
Some(path) => echo_file(path.to_string(), fs),
|
||||||
|
|
||||||
None => println!("No path provided"),
|
None => println!("No path provided"),
|
||||||
},
|
},
|
||||||
"test" => {}
|
"test" => {}
|
||||||
|
=======
|
||||||
|
// "echo" => {
|
||||||
|
// echo_file(iter.next().unwrap().to_string(), fs);
|
||||||
|
// }
|
||||||
|
>>>>>>> 5149f26... vfs: move operations into trait StorageDevice, hold StorageDevices in KERNEL_STATE
|
||||||
|
|
||||||
"quit" => shutdown(),
|
"quit" => shutdown(),
|
||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
let mut options = OpenOptions::new();
|
// let mut options = OpenOptions::new();
|
||||||
options.read(true);
|
// options.read(true);
|
||||||
let file = {
|
// let file = {
|
||||||
let path = format!("/home/{user}/bins/{bin_name}.wasm");
|
// let path = format!("/home/{user}/bins/{bin_name}.wasm");
|
||||||
if let Ok(file) = fs.open(&path.as_bytes(), &options) {
|
// if let Ok(file) = fs.open(&path.as_bytes(), &options) {
|
||||||
file
|
// file
|
||||||
} else {
|
// } else {
|
||||||
let path = format!("/shared/bins/{bin_name}.wasm");
|
// let path = format!("/shared/bins/{bin_name}.wasm");
|
||||||
if let Ok(file) = fs.open(&path.as_bytes(), &options) {
|
// if let Ok(file) = fs.open(&path.as_bytes(), &options) {
|
||||||
file
|
// file
|
||||||
} else {
|
// } else {
|
||||||
let path = format!("/system/bins/{bin_name}.wasm");
|
// let path = format!("/system/bins/{bin_name}.wasm");
|
||||||
match fs.open(&path.as_bytes(), &options) {
|
// match fs.open(&path.as_bytes(), &options) {
|
||||||
Ok(file) => file,
|
// Ok(file) => file,
|
||||||
Err(error) => {
|
// Err(error) => {
|
||||||
trace!("{:?}", error);
|
// trace!("{:?}", error);
|
||||||
println!("No such binary: {}", bin_name);
|
println!("No such binary: {}", bin_name);
|
||||||
error!("No such binary: {}", bin_name);
|
error!("No such binary: {}", bin_name);
|
||||||
return;
|
return;
|
||||||
|
<<<<<<< HEAD
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -272,6 +279,20 @@ pub fn command_parser(user: String, command: String) {
|
||||||
// let args = iter.collect::<Vec<&str>>();
|
// let args = iter.collect::<Vec<&str>>();
|
||||||
// println!("{:?}", args);
|
// println!("{:?}", args);
|
||||||
run_program(&binary);
|
run_program(&binary);
|
||||||
|
=======
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
|
||||||
|
// let mut binary = vec![];
|
||||||
|
// file.read_to_end(&mut binary).unwrap();
|
||||||
|
|
||||||
|
// let args = iter.collect::<Vec<&str>>();
|
||||||
|
// println!("{:?}", args);
|
||||||
|
// run_program(&binary);
|
||||||
|
>>>>>>> 5149f26... vfs: move operations into trait StorageDevice, hold StorageDevices in KERNEL_STATE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,101 +1,101 @@
|
||||||
pub mod host_functions;
|
pub mod host_functions;
|
||||||
|
|
||||||
use crate::{filesystem::FILE_SYSTEM, wasm_jumploader::host_functions::HostExternals};
|
use crate::wasm_jumploader::host_functions::HostExternals;
|
||||||
use genfs::{Fs, OpenOptions};
|
// use genfs::{Fs, OpenOptions};
|
||||||
use wasmi::{ImportsBuilder, ModuleInstance};
|
use wasmi::{ImportsBuilder, ModuleInstance};
|
||||||
|
|
||||||
pub fn interp() {
|
pub fn interp() {
|
||||||
trace!("Interpreting...");
|
trace!("Interpreting...");
|
||||||
let fs = &*FILE_SYSTEM.lock();
|
// let fs = &*FILE_SYSTEM.lock();
|
||||||
trace!("Got filesystem");
|
// trace!("Got filesystem");
|
||||||
let file = fs
|
// let file = fs
|
||||||
.open(
|
// .open(
|
||||||
b"/home/able/bins/aos_test.wasm",
|
// b"/home/able/bins/aos_test.wasm",
|
||||||
OpenOptions::new().read(true),
|
// OpenOptions::new().read(true),
|
||||||
)
|
// )
|
||||||
.unwrap();
|
// .unwrap();
|
||||||
|
|
||||||
let mut wasm_binary = Vec::new();
|
// let mut wasm_binary = Vec::new();
|
||||||
|
|
||||||
let ret = file.read_to_end(&mut wasm_binary).unwrap();
|
// let ret = file.read_to_end(&mut wasm_binary).unwrap();
|
||||||
trace!("Binary size {}", ret);
|
// trace!("Binary size {}", ret);
|
||||||
// Load wasm binary and prepare it for instantiation.
|
// // Load wasm binary and prepare it for instantiation.
|
||||||
let module = wasmi::Module::from_buffer(&wasm_binary).expect("failed to load wasm");
|
// let module = wasmi::Module::from_buffer(&wasm_binary).expect("failed to load wasm");
|
||||||
trace!("Loaded wasm binary");
|
// trace!("Loaded wasm binary");
|
||||||
let imports = ImportsBuilder::new().with_resolver("env", &host_functions::HostExternals {});
|
// let imports = ImportsBuilder::new().with_resolver("env", &host_functions::HostExternals {});
|
||||||
trace!("Created imports");
|
// trace!("Created imports");
|
||||||
|
|
||||||
// Instantiate a module with empty imports and
|
// // Instantiate a module with empty imports and
|
||||||
// assert that there is no `start` function.
|
// // assert that there is no `start` function.
|
||||||
let instance = ModuleInstance::new(&module, &imports); // .expect("failed to instantiate wasm module")
|
// let instance = ModuleInstance::new(&module, &imports); // .expect("failed to instantiate wasm module")
|
||||||
|
|
||||||
match instance {
|
// match instance {
|
||||||
Ok(inst) => {
|
// Ok(inst) => {
|
||||||
let instance = inst.assert_no_start();
|
// let instance = inst.assert_no_start();
|
||||||
let mut is_driver = false;
|
// let mut is_driver = false;
|
||||||
let _is_program = false;
|
// let _is_program = false;
|
||||||
let mut has_driver_entry = false;
|
// let mut has_driver_entry = false;
|
||||||
let mut has_driver_exit = false;
|
// let mut has_driver_exit = false;
|
||||||
let mut has_start = false;
|
// let mut has_start = false;
|
||||||
|
|
||||||
if let Some(_val) = instance.export_by_name("driver_entry") {
|
// if let Some(_val) = instance.export_by_name("driver_entry") {
|
||||||
has_driver_entry = true;
|
// has_driver_entry = true;
|
||||||
}
|
// }
|
||||||
|
|
||||||
if let Some(_val) = instance.export_by_name("driver_exit") {
|
// if let Some(_val) = instance.export_by_name("driver_exit") {
|
||||||
has_driver_exit = true;
|
// has_driver_exit = true;
|
||||||
}
|
// }
|
||||||
|
|
||||||
match instance.export_by_name("start") {
|
// match instance.export_by_name("start") {
|
||||||
Some(_val) => {
|
// Some(_val) => {
|
||||||
trace!("Program start function found");
|
// trace!("Program start function found");
|
||||||
has_start = true;
|
// has_start = true;
|
||||||
}
|
// }
|
||||||
None => debug!("No start function found"),
|
// None => debug!("No start function found"),
|
||||||
}
|
// }
|
||||||
|
|
||||||
match instance.export_by_name("main") {
|
// match instance.export_by_name("main") {
|
||||||
Some(_val) => {
|
// Some(_val) => {
|
||||||
trace!("Program main function found");
|
// trace!("Program main function found");
|
||||||
has_start = true;
|
// has_start = true;
|
||||||
}
|
// }
|
||||||
None => debug!("No main function found"),
|
// None => debug!("No main function found"),
|
||||||
}
|
// }
|
||||||
|
|
||||||
match (has_driver_entry, has_driver_exit) {
|
// match (has_driver_entry, has_driver_exit) {
|
||||||
(true, true) => {
|
// (true, true) => {
|
||||||
trace!("Valid driver entry and exit functions found");
|
// trace!("Valid driver entry and exit functions found");
|
||||||
is_driver = true;
|
// is_driver = true;
|
||||||
}
|
// }
|
||||||
(true, false) => error!("Driver entry function found but no driver exit function"),
|
// (true, false) => error!("Driver entry function found but no driver exit function"),
|
||||||
(false, true) => error!("Driver exit function found but no driver entry function"),
|
// (false, true) => error!("Driver exit function found but no driver entry function"),
|
||||||
(false, false) => {
|
// (false, false) => {
|
||||||
trace!("No driver entry or exit functions found");
|
// trace!("No driver entry or exit functions found");
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
if has_start && has_driver_entry {
|
// if has_start && has_driver_entry {
|
||||||
error!(
|
// error!(
|
||||||
"A program should not have both a start function and a driver entry function. It Will be treated as a program."
|
// "A program should not have both a start function and a driver entry function. It Will be treated as a program."
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
|
|
||||||
if has_start {
|
// if has_start {
|
||||||
let ret = instance
|
// let ret = instance
|
||||||
.invoke_export("start", &[], &mut HostExternals {})
|
// .invoke_export("start", &[], &mut HostExternals {})
|
||||||
.expect("failed to execute export");
|
// .expect("failed to execute export");
|
||||||
|
|
||||||
println!("collected wasm return value: {:?}", ret);
|
// println!("collected wasm return value: {:?}", ret);
|
||||||
} else if is_driver {
|
// } else if is_driver {
|
||||||
let ret = instance
|
// let ret = instance
|
||||||
.invoke_export("driver_entry", &[], &mut HostExternals {})
|
// .invoke_export("driver_entry", &[], &mut HostExternals {})
|
||||||
.expect("failed to execute export");
|
// .expect("failed to execute export");
|
||||||
|
|
||||||
println!("collected wasm return value: {:?}", ret);
|
// println!("collected wasm return value: {:?}", ret);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
Err(err) => error!("{}", err),
|
// Err(err) => error!("{}", err),
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_program(program: &[u8]) {
|
pub fn run_program(program: &[u8]) {
|
||||||
|
|
|
@ -62,8 +62,8 @@ pub enum Error {
|
||||||
/// inode name
|
/// inode name
|
||||||
name: String,
|
name: String,
|
||||||
},
|
},
|
||||||
#[cfg(any(test, not(feature = "no_std")))]
|
// #[cfg(any(test, not(feature = "no_std")))]
|
||||||
Io { inner: io::Error },
|
// Io { inner: io::Error },
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for Error {
|
impl Display for Error {
|
||||||
|
|
Loading…
Reference in a new issue