From d17232ffd5d84cf76700537848a877b3896fd4fa Mon Sep 17 00:00:00 2001 From: George Malandrakis Date: Thu, 7 Sep 2023 11:19:28 +0200 Subject: [PATCH 1/5] Mutex & Safe access to FatDriver --- kernel/src/filesystem/fat.rs | 38 ++++++++++++++++++++++-------------- kernel/src/filesystem/mod.rs | 0 kernel/src/main.rs | 10 ++++++---- kernel/src/shell/mod.rs | 0 kernel/src/shell/shell.rs | 21 +++++++++++++------- 5 files changed, 43 insertions(+), 26 deletions(-) mode change 100644 => 100755 kernel/src/filesystem/fat.rs mode change 100644 => 100755 kernel/src/filesystem/mod.rs mode change 100644 => 100755 kernel/src/main.rs mode change 100644 => 100755 kernel/src/shell/mod.rs mode change 100644 => 100755 kernel/src/shell/shell.rs diff --git a/kernel/src/filesystem/fat.rs b/kernel/src/filesystem/fat.rs old mode 100644 new mode 100755 index ec98da2..5906996 --- a/kernel/src/filesystem/fat.rs +++ b/kernel/src/filesystem/fat.rs @@ -2,21 +2,24 @@ use crate::drivers::disk::DISK; use core::mem; +use core::sync::atomic::AtomicBool; +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: Mutex = 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; const FAT_SIZE: usize = 256; + + //FAT16 header #[derive(Copy, Clone, Debug)] #[repr(C, packed)] @@ -48,7 +51,7 @@ pub struct Header { zero: [u8; 460], //needed to make struct 512 bytes big } -static NULL_HEADER: Header = Header { +pub static NULL_HEADER: Header = Header { boot_jump_instructions: [0; 3], oem_identifier: [0; 8], @@ -92,7 +95,7 @@ pub struct Entry { size: u32, } -static NULL_ENTRY: Entry = Entry { +pub static NULL_ENTRY: Entry = Entry { name: [0; 11], attributes: 0, reserved: 0, @@ -107,9 +110,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], } @@ -130,13 +135,14 @@ 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::() as u16; let lba: u64 = FAT_START as u64 + (self.header.reserved_sectors - + self.header.sectors_per_fat * self.header.fat_count as u16) as u64; + + self.header.sectors_per_fat * self.header.fat_count as u16) as u64; let size: u16 = entry_size * self.header.dir_entries_count; let sectors: u16 = size / self.header.bytes_per_sector; @@ -145,7 +151,9 @@ impl FatDriver { DISK.read(target, lba, sectors); } } - + pub fn testf(&mut self) -> i32 { + return 0; + } //list each entry in root direcotry //TODO: add other info like creation_date ecc pub fn list_entries(&self) { @@ -186,13 +194,13 @@ 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 - + self.header.sectors_per_fat * self.header.fat_count as u16 - + 32) as u64; + + self.header.sectors_per_fat * self.header.fat_count as u16 + + 32) as u64; let lba: u64 = data_lba + ((entry.first_cluster_low - 2) * self.header.sectors_per_cluster as u16) as u64; @@ -204,7 +212,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; @@ -212,8 +220,8 @@ impl FatDriver { loop { let data_lba: u64 = FAT_START as u64 + (self.header.reserved_sectors - + self.header.sectors_per_fat * self.header.fat_count as u16 - + 32) as u64; + + self.header.sectors_per_fat * self.header.fat_count as u16 + + 32) as u64; let lba: u64 = data_lba + ((next_cluster - 2) * self.header.sectors_per_cluster as u16) as u64; diff --git a/kernel/src/filesystem/mod.rs b/kernel/src/filesystem/mod.rs old mode 100644 new mode 100755 diff --git a/kernel/src/main.rs b/kernel/src/main.rs old mode 100644 new mode 100755 index 5fd7090..1237398 --- a/kernel/src/main.rs +++ b/kernel/src/main.rs @@ -17,7 +17,6 @@ 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; @@ -27,6 +26,7 @@ use syscalls::print::PRINTER; use multitasking::task::TASK_MANAGER; use libfelix; +use crate::filesystem::fat::{FAT_MUTEX, FatDriver, NULL_ENTRY, NULL_HEADER}; #[global_allocator] static ALLOCATOR: Allocator = Allocator; @@ -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_MUTEX.acquire_mut(); + fat.load_header(); + fat.load_table(); + fat.load_entries(); + FAT_MUTEX.free(); } //print name, version and copyright diff --git a/kernel/src/shell/mod.rs b/kernel/src/shell/mod.rs old mode 100644 new mode 100755 diff --git a/kernel/src/shell/shell.rs b/kernel/src/shell/shell.rs old mode 100644 new mode 100755 index 5235f5e..1f88382 --- a/kernel/src/shell/shell.rs +++ b/kernel/src/shell/shell.rs @@ -1,6 +1,6 @@ //SHELL -use crate::filesystem::fat::FAT; +use crate::filesystem::fat::{FAT_MUTEX}; use crate::multitasking::task::TASK_MANAGER; use crate::syscalls::print::PRINTER; @@ -97,7 +97,8 @@ impl Shell { //list root directory _b if self.is_command("ls") => unsafe { - FAT.list_entries(); + FAT_MUTEX.acquire().list_entries(); + FAT_MUTEX.free(); }, //list running tasks @@ -169,13 +170,15 @@ impl Shell { for i in 4..15 { self.arg[i - 4] = b[i]; } + let fat_driver = FAT_MUTEX.acquire(); - let entry = FAT.search_file(&self.arg); + let entry = fat_driver.search_file(&self.arg); if entry.name[0] != 0 { - FAT.read_file_to_buffer(entry); - for c in FAT.buffer { + fat_driver.read_file_to_buffer(entry); + + for c in fat_driver.buffer { if c != 0 { libfelix::print!("{}", c as char); } @@ -184,6 +187,7 @@ impl Shell { } else { libfelix::println!("File not found!"); } + FAT_MUTEX.free(); } //loads an executable as a task @@ -191,8 +195,9 @@ impl Shell { for i in 4..15 { self.arg[i - 4] = b[i]; } + let ft = FAT_MUTEX.acquire(); - let entry = FAT.search_file(&self.arg); + let entry = ft.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); @@ -201,7 +206,7 @@ impl Shell { TABLES[8].set(target); PAGING.set_table(8, &TABLES[8]); - FAT.read_file_to_target(&entry, target as *mut u32); + ft.read_file_to_target(&entry, target as *mut u32); unsafe { let signature = *(target as *mut u32); @@ -215,6 +220,8 @@ impl Shell { } else { libfelix::println!("Program not found!"); } + FAT_MUTEX.free(); + } pub fn is_command(&self, command: &str) -> bool { From 527a5a806b7c97905b29ae935ec2e23406d38d0a Mon Sep 17 00:00:00 2001 From: George Malandrakis Date: Thu, 7 Sep 2023 11:31:26 +0200 Subject: [PATCH 2/5] Mutex.rs --- lib/Cargo.toml | 0 lib/src/lib.rs | 2 ++ lib/src/mutex.rs | 47 +++++++++++++++++++++++++++++++++++++++++++++++ lib/src/print.rs | 0 4 files changed, 49 insertions(+) mode change 100644 => 100755 lib/Cargo.toml mode change 100644 => 100755 lib/src/lib.rs create mode 100755 lib/src/mutex.rs mode change 100644 => 100755 lib/src/print.rs diff --git a/lib/Cargo.toml b/lib/Cargo.toml old mode 100644 new mode 100755 diff --git a/lib/src/lib.rs b/lib/src/lib.rs old mode 100644 new mode 100755 index 9e8d96a..0ae7548 --- a/lib/src/lib.rs +++ b/lib/src/lib.rs @@ -1,3 +1,5 @@ #![no_std] + pub mod print; +pub mod mutex; diff --git a/lib/src/mutex.rs b/lib/src/mutex.rs new file mode 100755 index 0000000..fd9b12b --- /dev/null +++ b/lib/src/mutex.rs @@ -0,0 +1,47 @@ +use core::fmt; +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 { + target: T, + free: AtomicBool, +} + +impl Mutex { + 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. No 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. No 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 Drop for Mutex { + fn drop(&mut self) { + self.free = AtomicBool::from(true); + } +} + diff --git a/lib/src/print.rs b/lib/src/print.rs old mode 100644 new mode 100755 From f3331e06c70e422babe0c07ecb793cb3ca52737a Mon Sep 17 00:00:00 2001 From: George Malandrakis <33784380+malandrakisgeo@users.noreply.github.com> Date: Thu, 7 Sep 2023 10:06:03 +0000 Subject: [PATCH 3/5] Typo --- lib/src/mutex.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/mutex.rs b/lib/src/mutex.rs index fd9b12b..c3abc54 100755 --- a/lib/src/mutex.rs +++ b/lib/src/mutex.rs @@ -20,14 +20,14 @@ impl Mutex { } } - //WARNING: You MUST call free() after using acquire() or acquire_mut() when the target is no longer needed. No doing so can, and will, lead to problems. + //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. No doing so can, and will, lead to problems. + //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 From 30253aa112b7c2c71956b67bcaa92aee38f7a2b7 Mon Sep 17 00:00:00 2001 From: George Malandrakis <33784380+malandrakisgeo@users.noreply.github.com> Date: Fri, 8 Sep 2023 06:35:54 +0000 Subject: [PATCH 4/5] Test function removed --- kernel/src/filesystem/fat.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/kernel/src/filesystem/fat.rs b/kernel/src/filesystem/fat.rs index 5906996..8640fc8 100755 --- a/kernel/src/filesystem/fat.rs +++ b/kernel/src/filesystem/fat.rs @@ -151,9 +151,7 @@ impl FatDriver { DISK.read(target, lba, sectors); } } - pub fn testf(&mut self) -> i32 { - return 0; - } + //list each entry in root direcotry //TODO: add other info like creation_date ecc pub fn list_entries(&self) { From 685c8266d8d24219100707e2e8246381c0c4df5c Mon Sep 17 00:00:00 2001 From: Gianmatteo Palmieri Date: Sat, 9 Sep 2023 12:43:54 +0200 Subject: [PATCH 5/5] Cleanup Signed-off-by: Gianmatteo Palmieri --- bootloader/src/splash.rs | 10 +++++----- kernel/src/filesystem/fat.rs | 24 ++++++++++-------------- kernel/src/main.rs | 6 +++--- kernel/src/shell/shell.rs | 26 ++++++++++++-------------- lib/src/lib.rs | 3 +-- lib/src/mutex.rs | 18 ++++++++---------- 6 files changed, 39 insertions(+), 48 deletions(-) diff --git a/bootloader/src/splash.rs b/bootloader/src/splash.rs index 9729426..ef29061 100644 --- a/bootloader/src/splash.rs +++ b/bootloader/src/splash.rs @@ -1,5 +1,5 @@ -pub const SPLASH: &'static str = -"▄ ▄ ▄ +pub const SPLASH: &'static str = + "▄ ▄ ▄ ██▄ ▄██ █ ▀█▄ ▄█▀▐█ █ ▀▄ ▄▀ ▐█ @@ -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() { @@ -33,8 +33,8 @@ pub fn splash() { '▌' => print!("{}", 0xdd as char), '▄' => print!("{}", 0xdc as char), '█' => print!("{}", 0xdb as char), - '\n' => {}, + '\n' => {} _ => print!("{}", c), } } -} \ No newline at end of file +} diff --git a/kernel/src/filesystem/fat.rs b/kernel/src/filesystem/fat.rs index 8640fc8..98e15e1 100755 --- a/kernel/src/filesystem/fat.rs +++ b/kernel/src/filesystem/fat.rs @@ -2,24 +2,20 @@ use crate::drivers::disk::DISK; use core::mem; -use core::sync::atomic::AtomicBool; use libfelix::mutex::Mutex; -//Warning! Mutable static here -pub static mut FAT_MUTEX: Mutex = Mutex::new( FatDriver { +pub static mut FAT: Mutex = 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; const FAT_SIZE: usize = 256; - - //FAT16 header #[derive(Copy, Clone, Debug)] #[repr(C, packed)] @@ -51,7 +47,7 @@ pub struct Header { zero: [u8; 460], //needed to make struct 512 bytes big } -pub static NULL_HEADER: Header = Header { +static NULL_HEADER: Header = Header { boot_jump_instructions: [0; 3], oem_identifier: [0; 8], @@ -95,7 +91,7 @@ pub struct Entry { size: u32, } -pub static NULL_ENTRY: Entry = Entry { +static NULL_ENTRY: Entry = Entry { name: [0; 11], attributes: 0, reserved: 0, @@ -142,7 +138,7 @@ impl FatDriver { let lba: u64 = FAT_START as u64 + (self.header.reserved_sectors - + self.header.sectors_per_fat * self.header.fat_count as u16) as u64; + + self.header.sectors_per_fat * self.header.fat_count as u16) as u64; let size: u16 = entry_size * self.header.dir_entries_count; let sectors: u16 = size / self.header.bytes_per_sector; @@ -193,12 +189,12 @@ impl FatDriver { //read first cluster of file to buffer pub fn read_file_to_buffer(&self, entry: &Entry) { - let target = self.buffer.as_ptr() as *mut u8; + let target = self.buffer.as_ptr() as *mut u8; let data_lba: u64 = FAT_START as u64 + (self.header.reserved_sectors - + self.header.sectors_per_fat * self.header.fat_count as u16 - + 32) as u64; + + self.header.sectors_per_fat * self.header.fat_count as u16 + + 32) as u64; let lba: u64 = data_lba + ((entry.first_cluster_low - 2) * self.header.sectors_per_cluster as u16) as u64; @@ -218,8 +214,8 @@ impl FatDriver { loop { let data_lba: u64 = FAT_START as u64 + (self.header.reserved_sectors - + self.header.sectors_per_fat * self.header.fat_count as u16 - + 32) as u64; + + self.header.sectors_per_fat * self.header.fat_count as u16 + + 32) as u64; let lba: u64 = data_lba + ((next_cluster - 2) * self.header.sectors_per_cluster as u16) as u64; diff --git a/kernel/src/main.rs b/kernel/src/main.rs index 1237398..5959cc7 100755 --- a/kernel/src/main.rs +++ b/kernel/src/main.rs @@ -22,11 +22,11 @@ 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; use libfelix; -use crate::filesystem::fat::{FAT_MUTEX, FatDriver, NULL_ENTRY, NULL_HEADER}; #[global_allocator] static ALLOCATOR: Allocator = Allocator; @@ -80,11 +80,11 @@ pub extern "C" fn _start() -> ! { //init filesystem if DISK.enabled { - let fat = FAT_MUTEX.acquire_mut(); + let fat = FAT.acquire_mut(); fat.load_header(); fat.load_table(); fat.load_entries(); - FAT_MUTEX.free(); + FAT.free(); } //print name, version and copyright diff --git a/kernel/src/shell/shell.rs b/kernel/src/shell/shell.rs index 1f88382..effda02 100755 --- a/kernel/src/shell/shell.rs +++ b/kernel/src/shell/shell.rs @@ -1,6 +1,6 @@ //SHELL -use crate::filesystem::fat::{FAT_MUTEX}; +use crate::filesystem::fat::FAT; use crate::multitasking::task::TASK_MANAGER; use crate::syscalls::print::PRINTER; @@ -97,8 +97,8 @@ impl Shell { //list root directory _b if self.is_command("ls") => unsafe { - FAT_MUTEX.acquire().list_entries(); - FAT_MUTEX.free(); + FAT.acquire().list_entries(); + FAT.free(); }, //list running tasks @@ -170,15 +170,14 @@ impl Shell { for i in 4..15 { self.arg[i - 4] = b[i]; } - let fat_driver = FAT_MUTEX.acquire(); + let fat = FAT.acquire(); - let entry = fat_driver.search_file(&self.arg); + let entry = fat.search_file(&self.arg); if entry.name[0] != 0 { + fat.read_file_to_buffer(entry); - fat_driver.read_file_to_buffer(entry); - - for c in fat_driver.buffer { + for c in fat.buffer { if c != 0 { libfelix::print!("{}", c as char); } @@ -187,7 +186,7 @@ impl Shell { } else { libfelix::println!("File not found!"); } - FAT_MUTEX.free(); + FAT.free(); } //loads an executable as a task @@ -195,9 +194,9 @@ impl Shell { for i in 4..15 { self.arg[i - 4] = b[i]; } - let ft = FAT_MUTEX.acquire(); + let fat = FAT.acquire(); - let entry = ft.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); @@ -206,7 +205,7 @@ impl Shell { TABLES[8].set(target); PAGING.set_table(8, &TABLES[8]); - ft.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); @@ -220,8 +219,7 @@ impl Shell { } else { libfelix::println!("Program not found!"); } - FAT_MUTEX.free(); - + FAT.free(); } pub fn is_command(&self, command: &str) -> bool { diff --git a/lib/src/lib.rs b/lib/src/lib.rs index 0ae7548..8cc6829 100755 --- a/lib/src/lib.rs +++ b/lib/src/lib.rs @@ -1,5 +1,4 @@ #![no_std] - -pub mod print; pub mod mutex; +pub mod print; diff --git a/lib/src/mutex.rs b/lib/src/mutex.rs index c3abc54..fe5f372 100755 --- a/lib/src/mutex.rs +++ b/lib/src/mutex.rs @@ -1,15 +1,14 @@ -use core::fmt; 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 + 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 { - target: T, - free: AtomicBool, + target: T, + free: AtomicBool, } impl Mutex { @@ -39,9 +38,8 @@ impl Mutex { } } -impl Drop for Mutex { +impl Drop for Mutex { fn drop(&mut self) { self.free = AtomicBool::from(true); } } -