Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mutex & Safe access to FatDriver #9

Merged
merged 5 commits into from
Sep 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions bootloader/src/splash.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
pub const SPLASH: &'static str =
"▄ ▄ ▄
pub const SPLASH: &'static str =
"▄ ▄ ▄
██▄ ▄██
█ ▀█▄ ▄█▀▐█
█ ▀▄ ▄▀ ▐█
Expand All @@ -23,7 +23,7 @@ pub const SPLASH: &'static str =
▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▀▀▀▀▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄

Press any key to start...";

#[allow(dead_code)]
pub fn splash() {
for c in SPLASH.chars() {
Expand All @@ -33,8 +33,8 @@ pub fn splash() {
'▌' => print!("{}", 0xdd as char),
'▄' => print!("{}", 0xdc as char),
'█' => print!("{}", 0xdb as char),
'\n' => {},
'\n' => {}
_ => print!("{}", c),
}
}
}
}
18 changes: 10 additions & 8 deletions kernel/src/filesystem/fat.rs
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@

use crate::drivers::disk::DISK;
use core::mem;
use libfelix::mutex::Mutex;

//Warning! Mutable static here
//TODO: Implement a mutex to get safe access to this
pub static mut FAT: FatDriver = FatDriver {
pub static mut FAT: Mutex<FatDriver> = Mutex::new(FatDriver {
header: NULL_HEADER,
entries: [NULL_ENTRY; ENTRY_COUNT],
table: [0; FAT_SIZE],
buffer: [0; 2048],
};
});

const ENTRY_COUNT: usize = 512;
const FAT_START: u16 = 36864;
Expand Down Expand Up @@ -107,9 +106,11 @@ static NULL_ENTRY: Entry = Entry {
size: 0,
};

#[derive(Copy, Clone)]
pub struct FatDriver {
pub header: Header,
pub entries: [Entry; ENTRY_COUNT], //the root directory is an array of file entries
pub entries: [Entry; ENTRY_COUNT],
//the root directory is an array of file entries
pub table: [u16; FAT_SIZE],
pub buffer: [u8; 2048],
}
Expand All @@ -130,6 +131,7 @@ impl FatDriver {
//get entries array address and overwrite that mem location with data from root directory
//calculate size and position of root direcotry based on data from header
pub fn load_entries(&mut self) {
libfelix::print!(" loading entries");
let target = &mut self.entries as *mut Entry;

let entry_size = mem::size_of::<Entry>() as u16;
Expand Down Expand Up @@ -186,8 +188,8 @@ impl FatDriver {
}

//read first cluster of file to buffer
pub fn read_file_to_buffer(&mut self, entry: &Entry) {
let target = &mut self.buffer as *mut u8;
pub fn read_file_to_buffer(&self, entry: &Entry) {
let target = self.buffer.as_ptr() as *mut u8;

let data_lba: u64 = FAT_START as u64
+ (self.header.reserved_sectors
Expand All @@ -204,7 +206,7 @@ impl FatDriver {
}

//read file reading one cluster at time
pub fn read_file_to_target(&mut self, entry: &Entry, target: *mut u32) {
pub fn read_file_to_target(&self, entry: &Entry, target: *mut u32) {
let mut next_cluster = entry.first_cluster_low;
let mut current_target = target;

Expand Down
Empty file modified kernel/src/filesystem/mod.rs
100644 → 100755
Empty file.
10 changes: 6 additions & 4 deletions kernel/src/main.rs
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ use core::arch::asm;
use core::panic::PanicInfo;
use drivers::disk::DISK;
use drivers::pic::PICS;
use filesystem::fat::FAT;
use interrupts::idt::IDT;
use memory::allocator::Allocator;
use memory::paging::PAGING;
use shell::shell::SHELL;
use syscalls::print::PRINTER;
use filesystem::fat::FAT;

use multitasking::task::TASK_MANAGER;

Expand Down Expand Up @@ -80,9 +80,11 @@ pub extern "C" fn _start() -> ! {

//init filesystem
if DISK.enabled {
FAT.load_header();
FAT.load_entries();
FAT.load_table();
let fat = FAT.acquire_mut();
fat.load_header();
fat.load_table();
fat.load_entries();
FAT.free();
}

//print name, version and copyright
Expand Down
Empty file modified kernel/src/shell/mod.rs
100644 → 100755
Empty file.
17 changes: 11 additions & 6 deletions kernel/src/shell/shell.rs
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@ impl Shell {

//list root directory
_b if self.is_command("ls") => unsafe {
FAT.list_entries();
FAT.acquire().list_entries();
FAT.free();
},

//list running tasks
Expand Down Expand Up @@ -169,13 +170,14 @@ impl Shell {
for i in 4..15 {
self.arg[i - 4] = b[i];
}
let fat = FAT.acquire();

let entry = FAT.search_file(&self.arg);
let entry = fat.search_file(&self.arg);

if entry.name[0] != 0 {
FAT.read_file_to_buffer(entry);
fat.read_file_to_buffer(entry);

for c in FAT.buffer {
for c in fat.buffer {
if c != 0 {
libfelix::print!("{}", c as char);
}
Expand All @@ -184,15 +186,17 @@ impl Shell {
} else {
libfelix::println!("File not found!");
}
FAT.free();
}

//loads an executable as a task
pub unsafe fn run(&mut self, b: &[char]) {
for i in 4..15 {
self.arg[i - 4] = b[i];
}
let fat = FAT.acquire();

let entry = FAT.search_file(&self.arg);
let entry = fat.search_file(&self.arg);
if entry.name[0] != 0 {
let slot = TASK_MANAGER.get_free_slot();
let target = APP_TARGET + (slot as u32 * APP_SIZE);
Expand All @@ -201,7 +205,7 @@ impl Shell {
TABLES[8].set(target);
PAGING.set_table(8, &TABLES[8]);

FAT.read_file_to_target(&entry, target as *mut u32);
fat.read_file_to_target(&entry, target as *mut u32);

unsafe {
let signature = *(target as *mut u32);
Expand All @@ -215,6 +219,7 @@ impl Shell {
} else {
libfelix::println!("Program not found!");
}
FAT.free();
}

pub fn is_command(&self, command: &str) -> bool {
Expand Down
Empty file modified lib/Cargo.toml
100644 → 100755
Empty file.
1 change: 1 addition & 0 deletions lib/src/lib.rs
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#![no_std]

pub mod mutex;
pub mod print;
45 changes: 45 additions & 0 deletions lib/src/mutex.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
use core::sync::atomic::{AtomicBool, Ordering};
/*
This is a oversimplified mutex created from scratch. Meant to be used for global, static definitions of objects, visible for all active threads. Once a thread acquires the target object, all other threads trying to do so will wait until it is freed.

There is plenty of room for improvements, since there are no mechanisms for e.g. creating a queue of threads that requested access to an object and giving it to the first that needs it.

TODO: Improve it
*/
pub struct Mutex<T> {
target: T,
free: AtomicBool,
}

impl<T> Mutex<T> {
pub const fn new(value: T) -> Self {
Self {
target: value,
free: AtomicBool::new(true),
}
}

//WARNING: You MUST call free() after using acquire() or acquire_mut() when the target is no longer needed. Not doing so can, and will, lead to problems.
pub fn acquire_mut(&mut self) -> &mut T {
while !self.free.load(Ordering::SeqCst) {} // Wait until free is true
self.free.store(false, Ordering::SeqCst); // Set free to false
return &mut self.target;
}

//WARNING: You MUST call free() after using acquire() or acquire_mut() when the target is no longer needed. Not doing so can, and will, lead to problems.
pub fn acquire(&mut self) -> &T {
while !self.free.load(Ordering::SeqCst) {} // Wait until free is true
self.free.store(false, Ordering::SeqCst); // Set free to false
return &self.target;
}

pub fn free(&self) {
self.free.store(true, Ordering::SeqCst); // Set free to true
}
}

impl<T> Drop for Mutex<T> {
fn drop(&mut self) {
self.free = AtomicBool::from(true);
}
}
Empty file modified lib/src/print.rs
100644 → 100755
Empty file.