Load app from sdcard on K210, but panicked on qemu.
This commit is contained in:
parent
760de97155
commit
a3802a4b91
18 changed files with 177 additions and 142 deletions
104
os/src/fs/inode.rs
Normal file
104
os/src/fs/inode.rs
Normal file
|
@ -0,0 +1,104 @@
|
|||
use easy_fs::{
|
||||
EasyFileSystem,
|
||||
Inode,
|
||||
};
|
||||
use crate::drivers::BLOCK_DEVICE;
|
||||
use alloc::sync::Arc;
|
||||
use lazy_static::*;
|
||||
use bitflags::*;
|
||||
use alloc::vec::Vec;
|
||||
use spin::Mutex;
|
||||
|
||||
pub struct OSInode {
|
||||
readable: bool,
|
||||
writable: bool,
|
||||
inner: Mutex<OSInodeInner>,
|
||||
}
|
||||
|
||||
pub struct OSInodeInner {
|
||||
offset: usize,
|
||||
inode: Arc<Inode>,
|
||||
}
|
||||
|
||||
impl OSInode {
|
||||
pub fn new(
|
||||
readable: bool,
|
||||
writable: bool,
|
||||
inode: Arc<Inode>,
|
||||
) -> Self {
|
||||
Self {
|
||||
readable,
|
||||
writable,
|
||||
inner: Mutex::new(OSInodeInner {
|
||||
offset: 0,
|
||||
inode,
|
||||
}),
|
||||
}
|
||||
}
|
||||
pub fn read_all(&self) -> Vec<u8> {
|
||||
let mut inner = self.inner.lock();
|
||||
let mut buffer = [0u8; 512];
|
||||
let mut v: Vec<u8> = Vec::new();
|
||||
loop {
|
||||
let len = inner.inode.read_at(inner.offset, &mut buffer);
|
||||
if len == 0 {
|
||||
break;
|
||||
}
|
||||
inner.offset += len;
|
||||
v.extend_from_slice(&buffer[..len]);
|
||||
}
|
||||
v
|
||||
}
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
pub static ref ROOT_INODE: Arc<Inode> = {
|
||||
let efs = EasyFileSystem::open(BLOCK_DEVICE.clone());
|
||||
Arc::new(EasyFileSystem::root_inode(&efs))
|
||||
};
|
||||
}
|
||||
|
||||
pub fn list_apps() {
|
||||
println!("/**** APPS ****");
|
||||
for app in ROOT_INODE.ls() {
|
||||
println!("{}", app);
|
||||
}
|
||||
println!("**************/")
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
pub struct OpenFlags: u32 {
|
||||
const RDONLY = 0;
|
||||
const WRONLY = 1 << 0;
|
||||
const RDWR = 1 << 1;
|
||||
const CREATE = 1 << 9;
|
||||
const TRUNC = 1 << 10;
|
||||
}
|
||||
}
|
||||
|
||||
impl OpenFlags {
|
||||
/// Do not check validity for simplicity
|
||||
/// Return (readable, writable)
|
||||
pub fn read_write(&self) -> (bool, bool) {
|
||||
if self.is_empty() {
|
||||
(true, false)
|
||||
} else if self.contains(Self::WRONLY) {
|
||||
(false, true)
|
||||
} else {
|
||||
(true, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn open_file(name: &str, flags: OpenFlags) -> Option<Arc<OSInode>> {
|
||||
let (readable, writable) = flags.read_write();
|
||||
// TODO: do not support CREATE or TRUNC flags now
|
||||
ROOT_INODE.find(name)
|
||||
.map(|inode| {
|
||||
Arc::new(OSInode::new(
|
||||
readable,
|
||||
writable,
|
||||
inode
|
||||
))
|
||||
})
|
||||
}
|
|
@ -1,10 +1,13 @@
|
|||
mod pipe;
|
||||
mod stdio;
|
||||
mod inode;
|
||||
|
||||
use crate::mm::UserBuffer;
|
||||
use core::any::Any;
|
||||
|
||||
pub trait File : Any + Send + Sync {
|
||||
fn readable(&self) -> bool;
|
||||
fn writable(&self) -> bool;
|
||||
fn read(&self, buf: UserBuffer) -> usize;
|
||||
fn write(&self, buf: UserBuffer) -> usize;
|
||||
fn as_any_ref(&self) -> &dyn Any;
|
||||
|
@ -18,4 +21,5 @@ impl dyn File {
|
|||
}
|
||||
|
||||
pub use pipe::{Pipe, make_pipe};
|
||||
pub use stdio::{Stdin, Stdout};
|
||||
pub use stdio::{Stdin, Stdout};
|
||||
pub use inode::{OSInode, open_file, OpenFlags, list_apps};
|
|
@ -114,8 +114,10 @@ pub fn make_pipe() -> (Arc<Pipe>, Arc<Pipe>) {
|
|||
}
|
||||
|
||||
impl File for Pipe {
|
||||
fn readable(&self) -> bool { self.readable }
|
||||
fn writable(&self) -> bool { self.writable }
|
||||
fn read(&self, buf: UserBuffer) -> usize {
|
||||
assert_eq!(self.readable, true);
|
||||
assert_eq!(self.readable(), true);
|
||||
let mut buf_iter = buf.into_iter();
|
||||
let mut read_size = 0usize;
|
||||
loop {
|
||||
|
@ -141,7 +143,7 @@ impl File for Pipe {
|
|||
}
|
||||
}
|
||||
fn write(&self, buf: UserBuffer) -> usize {
|
||||
assert_eq!(self.writable, true);
|
||||
assert_eq!(self.writable(), true);
|
||||
let mut buf_iter = buf.into_iter();
|
||||
let mut write_size = 0usize;
|
||||
loop {
|
||||
|
|
|
@ -9,6 +9,8 @@ pub struct Stdin;
|
|||
pub struct Stdout;
|
||||
|
||||
impl File for Stdin {
|
||||
fn readable(&self) -> bool { true }
|
||||
fn writable(&self) -> bool { false }
|
||||
fn read(&self, mut user_buf: UserBuffer) -> usize {
|
||||
assert_eq!(user_buf.len(), 1);
|
||||
// busy loop
|
||||
|
@ -33,6 +35,8 @@ impl File for Stdin {
|
|||
}
|
||||
|
||||
impl File for Stdout {
|
||||
fn readable(&self) -> bool { false }
|
||||
fn writable(&self) -> bool { true }
|
||||
fn read(&self, _user_buf: UserBuffer) -> usize{
|
||||
panic!("Cannot read from stdout!");
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue