Skip to content

Commit

Permalink
wip: add file_handles
Browse files Browse the repository at this point in the history
  • Loading branch information
GZTimeWalker committed May 9, 2022
1 parent 7c82420 commit 339020b
Show file tree
Hide file tree
Showing 9 changed files with 119 additions and 11 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pkg/fs/src/device/disk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ pub enum VolumeError {
NotAFile,
ReadOnly,
Unsupported,
BufferTooSmall,
DeviceError(DeviceError),
FileNameError(FilenameError),
}
Expand Down
29 changes: 29 additions & 0 deletions pkg/fs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,3 +156,32 @@ where
}
Ok(data)
}

/// read a file
pub fn read_to_buf<T>(
volume: &FAT16Volume<T>,
file: &File,
buf: &mut [u8]
) -> Result<usize, VolumeError>
where
T: BlockDevice,
{
if buf.len() < file.length() as usize {
return Err(VolumeError::BufferTooSmall);
}
let mut length = file.length() as usize;
for i in 0..file.length() as usize / Block::SIZE + 1 {
let sector = volume.cluster_to_sector(&file.start_cluster());
let block = volume.read_block(sector as usize + i).unwrap();
if length > Block::SIZE {
buf[i * Block::SIZE..(i + 1) * Block::SIZE]
.copy_from_slice(&block.inner()[..]);
length -= Block::SIZE;
} else {
buf[i * Block::SIZE..i * Block::SIZE + length as usize]
.copy_from_slice(&block.inner()[..length as usize]);
break;
}
}
Ok(file.length() as usize)
}
4 changes: 2 additions & 2 deletions pkg/fs/src/structs/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
//! - https://wiki.osdev.org/FAT#Directories_on_FAT12.2F16.2F32
//! - https://github.com/rust-embedded-community/embedded-sdmmc-rs/blob/develop/src/filesystem.rs
use crate::dir_entry::*;
#[derive(Debug)]
use crate::*;
#[derive(Debug, Clone)]
pub struct File {
/// The starting point of the file.
pub start_cluster: Cluster,
Expand Down
2 changes: 1 addition & 1 deletion pkg/kernel/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ggos_kernel"
version = "0.6.3"
version = "0.6.4"
edition = "2021"
authors = ["GZTime <Time.GZ@outlook.com>"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand Down
19 changes: 14 additions & 5 deletions pkg/kernel/src/drivers/filesystem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,19 @@ pub type Volume = fs::device::FAT16Volume<Drive>;

pub static FILESYSTEM: spin::Once<Volume> = spin::Once::new();

fn fs() -> &'static Volume {
pub fn get_volume() -> &'static Volume {
FILESYSTEM.get().unwrap()
}

#[derive(Debug, Clone)]
pub struct StdIO;

impl StdIO {
pub fn new() -> Self {
Self {}
}
}

pub fn init() {
info!("Initializing filesystem...");

Expand All @@ -28,7 +37,7 @@ fn resolve_path(root_path: &str) -> Option<Directory> {
let dir = path[..pos].to_owned();

let tmp = fs::find_directory_entry(
fs(), &root, dir.as_str()
get_volume(), &root, dir.as_str()
);

if tmp.is_err() {
Expand Down Expand Up @@ -57,7 +66,7 @@ pub fn ls(root_path: &str) {

println!(" Size | Last Modified | Name");

if let Err(err) = fs::iterate_dir(fs(), &root, |entry| {
if let Err(err) = fs::iterate_dir(get_volume(), &root, |entry| {
println!("{}", entry);
}) {
println!("{:?}", err);
Expand All @@ -71,7 +80,7 @@ pub fn cat(root_path: &str, file: &str) {
None => return,
};

let file = fs::open_file(fs(), &root, file, file::Mode::ReadOnly);
let file = fs::open_file(get_volume(), &root, file, file::Mode::ReadOnly);

if file.is_err() {
warn!("ERROR: {:?}", file.unwrap_err());
Expand All @@ -80,7 +89,7 @@ pub fn cat(root_path: &str, file: &str) {

let file = file.unwrap();

let data = fs::read(fs(), &file);
let data = fs::read(get_volume(), &file);

if data.is_err() {
warn!("ERROR: {:?}", data.unwrap_err());
Expand Down
11 changes: 9 additions & 2 deletions pkg/kernel/src/process/process.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use super::ProgramStatus;
use crate::filesystem::StdIO;
use crate::memory::BootInfoFrameAllocator;
use crate::utils::{Registers, RegistersValue};
use crate::utils::{Registers, RegistersValue, Resource};
use crate::memory::physical_to_virtual;
use core::intrinsics::copy_nonoverlapping;
use x86_64::structures::paging::{OffsetPageTable, PhysFrame, PageTable};
Expand Down Expand Up @@ -30,12 +31,18 @@ pub struct Process {
#[derive(Clone, Debug, Default)]
pub struct ProcessData {
env: BTreeMap<String, String>,
file_handles: BTreeMap<u8, Resource>
}

impl ProcessData {
pub fn new() -> Self {
let env = BTreeMap::new();
Self { env }
let mut file_handles = BTreeMap::new();
// stdin, stdout, stderr
file_handles.insert(0, Resource::Console(StdIO::new()));
file_handles.insert(1, Resource::Console(StdIO::new()));
file_handles.insert(2, Resource::Console(StdIO::new()));
Self { env, file_handles }
}

pub fn set_env(mut self, key: &str, val: &str) -> Self {
Expand Down
2 changes: 2 additions & 0 deletions pkg/kernel/src/utils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ pub mod font;
pub mod colors;
pub mod logger;
pub mod clock;
pub mod resource;

pub use resource::Resource;
pub use macros::*;
pub use regs::*;

Expand Down
60 changes: 60 additions & 0 deletions pkg/kernel/src/utils/resource.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
use alloc::string::{String, ToString};
use fs::{Random, File, Device};
use pc_keyboard::DecodedKey;
use crate::input;

use crate::filesystem::{StdIO, get_volume};

#[derive(Debug, Clone)]
pub enum Resource {
File(File),
Console(StdIO),
Random(Random),
Null,
}

impl Resource {
pub fn read(&self, buf: &mut [u8]) -> Result<usize, ()> {
match self {
Resource::File(file) => {
fs::read_to_buf(get_volume(), file, buf)
.map_err(|_| ())
},
Resource::Console(_) => {
if buf.len() < 4 {
return Ok(0);
}
let mut s = if buf.len() == 4 {
if let DecodedKey::Unicode(c) = input::get_key() {
c.to_string()
} else {
return Ok(0);
}
} else {
input::get_line()
};

s.truncate(buf.len());
let n = s.len();
buf[..n].copy_from_slice(s.as_bytes());
Ok(n)
},
Resource::Random(random) => {
Ok(random.read(buf, 0, buf.len()).unwrap_or(0))
},
Resource::Null => Ok(0),
}
}

pub fn write(&self, buf: &[u8]) -> Result<usize, ()> {
match self {
Resource::File(_) => unimplemented!(),
Resource::Console(_) => {
print!("{}", String::from_utf8_lossy(buf));
Ok(buf.len())
},
Resource::Random(_) => Ok(0),
Resource::Null => Ok(0),
}
}
}

0 comments on commit 339020b

Please sign in to comment.