diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..e3660e1 --- /dev/null +++ b/build.rs @@ -0,0 +1,12 @@ +//! Build script for BurritOS. +//! +//! Moves files from the assets folder to the target directory +//! and runs `make all`. + +use std::process::Command; + +fn main() { + let mut make_all = Command::new("make"); + make_all.arg("all"); + println!("{:?}", make_all.output().unwrap()); +} \ No newline at end of file diff --git a/src/kernel/exception.rs b/src/kernel/exception.rs index 8505a87..9a5242f 100644 --- a/src/kernel/exception.rs +++ b/src/kernel/exception.rs @@ -1,3 +1,8 @@ +//! # Exceprions +//! +//! This module Enum the constant values of the exceptions. +//! They are used to stop the system to execute some opperation + use std::{cell::RefCell, rc::Rc}; use crate::{simulator::{machine::{ExceptionType, Machine}, error::{MachineOk, MachineError}}}; @@ -292,6 +297,7 @@ fn sc_new_thread(machine: &mut Machine, system: &mut System) -> Result Result { diff --git a/src/kernel/mgerror.rs b/src/kernel/mgerror.rs index dfe83c8..751284e 100644 --- a/src/kernel/mgerror.rs +++ b/src/kernel/mgerror.rs @@ -1,3 +1,11 @@ +//! # Error Code +//! +//! This module enumerate the possibles error code who could get in a function +//! +//! **Basic Usage:* +//! +//! Result pub enum ErrorCode { diff --git a/src/kernel/mod.rs b/src/kernel/mod.rs index df9b60d..a072709 100644 --- a/src/kernel/mod.rs +++ b/src/kernel/mod.rs @@ -1,3 +1,9 @@ +//! # Kernel +//! +//! This module contains all the tool required for the kernel to work. +//! +//! Currently it contains the scheduling and synchroisation tools, but it will contains the tools +//! required Memory gestion, Files gestion and peripheral pilots. pub mod process; pub mod thread; pub mod mgerror; diff --git a/src/kernel/synch.rs b/src/kernel/synch.rs index a1472e5..2b5cb88 100644 --- a/src/kernel/synch.rs +++ b/src/kernel/synch.rs @@ -1,3 +1,11 @@ +//! # Synchronisation +//! +//! This module contains some scheduling and synchronisation utilities: +//! - **Semaphore** +//! - **Lock** +//! +//! Conditions aren't implemented currently + use crate::utility::list::List; use crate::kernel::thread::Thread; use crate::simulator::interrupt::InterruptStatus::InterruptOff; @@ -6,20 +14,21 @@ use std::cell::RefCell; use std::rc::Rc; use super::thread_manager::ThreadManager; -/// Structure of a Semaphore used for synchronisation +/// Structure of a Semaphore used for synchronisation. +/// It use a counter to determine the number of thread that can be executed simultaneously. #[derive(PartialEq)] pub struct Semaphore { - /// Counter of simultanous Semaphore + /// Counter of simultaneous Semaphore pub counter:i32, - /// QUeue of Semaphore waiting to be exucated + /// QUeue of Semaphore waiting to be executed pub waiting_queue:List>>, } impl Semaphore { - /// Initializes a semaphore, so that it can be used for synchronization. + /// Initializes a semaphore, so that it can be used for synchronization. /// /// ### Parameters /// - *counter* initial value of counter @@ -49,7 +58,7 @@ pub struct Lock { impl Lock { /// Initialize a Lock, so that it can be used for synchronization. - /// The lock is initialy free + /// The lock is initially free /// /// ### Parameters /// - **thread_manager** Thread manager which managing threads @@ -72,7 +81,7 @@ impl Lock { let old_status = machine.interrupt.set_status(InterruptOff); if self.free { self.free = false; - self.owner = Option::Some(match thread_manager.get_g_current_thread() { + self.owner = Some(match thread_manager.get_g_current_thread() { Some(th) => { Rc::clone(&th) }, @@ -128,8 +137,14 @@ impl Lock { machine.interrupt.set_status(old_status); } - /// True if the current thread holds this lock. + /// Say if the lock is held by the current thread /// Useful for checking in Release, and in Condition operations below. + /// ### Parameters + /// - **self** The current lock + /// - **thread-manager** The thread manager present in the system + /// ### Return + /// True if the current thread holds this lock. + pub fn held_by_current_thread(&mut self, thread_manager: &mut ThreadManager) -> bool { match &self.owner { Some(x) => diff --git a/src/kernel/thread.rs b/src/kernel/thread.rs index d0bdc3e..91a4583 100644 --- a/src/kernel/thread.rs +++ b/src/kernel/thread.rs @@ -1,3 +1,6 @@ +//! # Thread +//! +//! use std::{rc::Rc, cell::RefCell}; use super::{process::Process, thread_manager::ThreadRef}; diff --git a/src/kernel/thread_manager.rs b/src/kernel/thread_manager.rs index 452d51b..7f67f8c 100644 --- a/src/kernel/thread_manager.rs +++ b/src/kernel/thread_manager.rs @@ -226,7 +226,7 @@ impl ThreadManager { } /// Relinquish the CPU if any other thread is runnable. - /// + /// /// If so, put the current thread at the end of the ready list, so it'll be re-scheduled in the future. /// /// **Returns** immediately if there's no other thread ready or return when the current thread has been switched. diff --git a/src/main.rs b/src/main.rs index 370d1f2..ea33dac 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,7 @@ - +#![doc( + html_logo_url = "https://gitlab.istic.univ-rennes1.fr/simpleos/burritos/-/raw/main/assets/logo/logo.svg", + html_favicon_url = "https://gitlab.istic.univ-rennes1.fr/simpleos/burritos/-/raw/main/assets/logo/logo.svg") +] #![warn(missing_docs)] #![warn(clippy::missing_docs_in_private_items)] @@ -7,10 +10,8 @@ //! Burritos is an educational operating system written in Rust //! running on RISC-V emulator. -/// Contain hardware simulated part of the machine mod simulator; mod kernel; -/// module containing useful tools which can be use in most part of the OS to ease the development of the OS pub mod utility; use std::{rc::Rc, cell::RefCell}; @@ -59,7 +60,6 @@ fn main() { system.get_thread_manager().set_sp_max(sp_max); system.get_thread_manager().start_thread(Rc::clone(&thread_exec), owner1, loader.elf_header.entrypoint, sp_max, -1); - let to_run = system.get_thread_manager().find_next_to_run().unwrap(); system.get_thread_manager().switch_to(&mut machine, Rc::clone(&to_run)); diff --git a/src/simulator/interrupt.rs b/src/simulator/interrupt.rs index c4be710..fd5ca7f 100644 --- a/src/simulator/interrupt.rs +++ b/src/simulator/interrupt.rs @@ -1,17 +1,38 @@ +//! # Interrupt +//! +//! This module contains an interrupt Handler. +//! The methodes one_trick and idle aren't implemented for now +/// # Interrupt +/// +/// Interrupt Handler #[derive(PartialEq)] pub struct Interrupt { + /// Current Status level: InterruptStatus } impl Interrupt { + /// Interrupt constructor + /// + /// ### Return + /// Interrupt with status Off pub fn new() -> Self { Self { level: InterruptStatus::InterruptOff } } + /// Interrupt setter + /// Change the value of the Interrupt + /// + /// ### Parameters + /// - **self** the interupt handler + /// - **new_status** the new status value + /// + /// ### return + /// The previus status pub fn set_status(&mut self, new_status: InterruptStatus) -> InterruptStatus { let old = self.level; self.level = new_status; @@ -25,6 +46,7 @@ impl Interrupt { todo!(); } + /// Interupt getter pub fn get_status(&self) -> InterruptStatus { self.level } diff --git a/src/simulator/loader.rs b/src/simulator/loader.rs index db3e610..7034282 100644 --- a/src/simulator/loader.rs +++ b/src/simulator/loader.rs @@ -1,9 +1,25 @@ +//! # Loader +//! +//! This module contains a loader for file section. +//! Following the common standard file format for executable files +//! [ELF (Executable and Linkable Format)](https://en.wikipedia.org/wiki/Executable_and_Linkable_Forma) +//! +//! It's used to charge a programme into the machine from a binary file (.guac files) +//! +//! Basic usage: +//! +//! ``` +//! let args = Args::parse(); +//! let mut machine = Machine::new(args.debug & 1 != 0, read_settings().unwrap()); +//! let (loader, ptr) = loader::Loader::new(args.executable.as_str(), &mut machine, 0).expect("An error occured while parsing the program"); +//! ``` + use crate::Machine; use std::fs; use std::io::Read; /// The elf header defines principes aspects of the binary files, it's place at the start of the file -/// see for more informations +/// see [ELF file Header](https://en.wikipedia.org/wiki/Executable_and_Linkable_Format#File_header) for more informations pub struct ElfHeader { /// Defines whether the file is big or little endian /// true correspond to big endian, false otherwise diff --git a/src/simulator/mem_cmp.rs b/src/simulator/mem_cmp.rs index 099d96f..1e12365 100644 --- a/src/simulator/mem_cmp.rs +++ b/src/simulator/mem_cmp.rs @@ -1,14 +1,31 @@ -///! FILE.TXT FORMAT Representing machine memory memory -/// - PC -/// - SP -/// - Section_1 -/// - Section_2 -/// - ... -/// - Section_n -/// -/// Each section is divided in 3 parts, on two lines of text -/// addr SPACE len -/// content +//! # Memory Comparator +//! +//! This module contains a MemChecker. +//! +//! It's used to compare state memory obtained after a dump memory from NachOS and BurritOS. +//! +//! This module is used exclusively for testing the instruction simulator. +//! +//! Basic usage: +//! +//! ``` +//! let mut m = Machine::new(true, get_debug_configuration()); +//! let mut MemChecker = mem_cmp::MemChecker::from(get_full_path!("memory", expr)); +//! mem_cmp::MemChecker::fill_memory_from_mem_checker(&MemChecker, &mut m); +//! ``` +//! +//! +//! ! FILE.TXT FORMAT Representing machine memory memory +//! - PC +//! - SP +//! - Section_1 +//! - Section_2 +//! - ... +//! - Section_n +//! +//! Each section is divided in 3 parts, on two lines of text +//! addr SPACE len +//! content use std::{fs, io::{BufRead, BufReader, Lines, Error}}; use crate::Machine; @@ -102,7 +119,7 @@ impl MemChecker { /// Extract the values of pc, sp and sections /// /// ### Parameter - /// -**path** addr to the file + /// - **path** addr to the file /// /// ### Return /// Mem-checker filled diff --git a/src/simulator/mmu.rs b/src/simulator/mmu.rs index 6436794..b91ace3 100644 --- a/src/simulator/mmu.rs +++ b/src/simulator/mmu.rs @@ -1,18 +1,38 @@ +//! # MMU +//! +//! This module contains a MMU implementation +//! +//! This part isn't tested nor integrated to BurritOS because of the lack of pagination implementation +//! +//! + use crate::simulator::translationtable::*; use crate::simulator::machine::*; +/// # Memory Management Unit +/// An MMU possesses a single reference to a translation table +/// This table is associated to the current process pub struct MMU <'a>{ - /* Un MMU possède une seule référence vers une table des pages à un instant donné - * Cette table est associée au processus courant - * Cette référence peut etre mise a jour par exemple lors d'un switchTo - */ + /// Reference to a page table translationTable : Option<&'a mut TranslationTable>, + /// The number of physique pages numPhyPages : u64, + /// Size of each page pageSize : u64 } impl <'a>MMU <'_>{ + /// Create a MMU with a None reference for the translation table + /// + /// ### Parameters + /// + /// - **numPhyPages** the number of physique pages + /// - **pageSize** the size of a page + /// + /// ### Return + /// + /// MMU with None reference and the value for the number of physical pages and pae size associated fn create(numPhyPages: u64, pageSize: u64) -> MMU <'a>{ MMU { translationTable : None, diff --git a/src/simulator/mod.rs b/src/simulator/mod.rs index a0e55ba..9a103b4 100644 --- a/src/simulator/mod.rs +++ b/src/simulator/mod.rs @@ -1,3 +1,12 @@ +//! This module implement an Instruction simulator +//! with all the simulated hardware requested to run the Machine : +//! - **MMU** +//! - **Processor** +//! - **RAM** +//! - **Interruption Controler** +//! +//! The disk, the console and the serial coupler aren't implmented for now +//! pub mod machine; pub mod error; pub mod instruction; diff --git a/src/simulator/translationtable.rs b/src/simulator/translationtable.rs index f0d7091..9dfbaa2 100644 --- a/src/simulator/translationtable.rs +++ b/src/simulator/translationtable.rs @@ -1,23 +1,35 @@ -//Nombre maximum de correspondances dans une table des pages -//Cette donnée devra a terme etre recupérée depuis un fichier de configuration +//! # Translation Table +//! +//! This module implement a trnslation table used for fot the MMU Emulator +//! +//! This part isn't tested nor integrated to BurritOS, +//! but will be useful in the futur when the pagination will be implemented. +//! +//! It contains: +//! - all the setters and getters for translation table +//! - modificaters of table values + + +/// Maximum number in a Page Table +/// For a futur evolution of program, this value should be load from a configuration file const MaxVirtPages : u64 = 200000; - -/* Une table de correspondance propre à un processus -* Une variable de type TranslationTable devra etre possédée par un objet de type Process - */ +/// Translation Table corresponding to a process +/// An iteration of type TranslationTable should be possesses by an oject of type Process pub struct TranslationTable{ - //capacité de cette table <=> nombre de correspondances possibles - //A voir si cette donnée doit etre immuable + /// Table size <=> nb of possible translation pub maxNumPages : u64, - //la table en question - //Vec implemente le trait Index, donc un bon choix + ///The table *Vec impemente Index Trait* pub pageTable : Vec } impl TranslationTable { + /// TranslationTable constructor + /// + /// ### Return + /// TranslationTable with an empty Vector pub fn create() -> TranslationTable { let mut tmp_vec : Vec = Vec::new(); diff --git a/src/utility/cfg.rs b/src/utility/cfg.rs index 87acfc4..7c687f5 100644 --- a/src/utility/cfg.rs +++ b/src/utility/cfg.rs @@ -104,6 +104,10 @@ pub fn get_debug_configuration() -> Settings { } /// Removes comments and empty lines +/// Filters out empty lines and comments from the reader `BufReader`. +/// +/// Returns a [`Vec`], each entry containing a valid +/// line from the input file. fn filter_garbage(reader: BufReader) -> Vec { reader.lines() .map(|l| l.unwrap()) @@ -111,11 +115,13 @@ fn filter_garbage(reader: BufReader) -> Vec { .collect() } - /// Inserts user settings into setting map +/// Adds a pair to a [`Settings`] map. +/// +/// Returns the updated [`Settings`]. fn update_settings_map(mut settings_map: Settings, key: &str, setting: &str) -> Settings { let key = MachineSettingKey::from(key); - let setting = setting.parse::().unwrap_or(0); + let setting = str::parse::(setting).unwrap_or(0); settings_map.insert(key, setting); settings_map } \ No newline at end of file diff --git a/src/utility/mod.rs b/src/utility/mod.rs index c6db391..85e59cc 100644 --- a/src/utility/mod.rs +++ b/src/utility/mod.rs @@ -1,3 +1,6 @@ +//! This module contains data type definitions used in other parts the BurritOS +//! They are separated from the rest of the operating system so as to promote +//! reusability and to separate data constructs proper from state and actions. pub mod list; pub mod objaddr; pub mod cfg; \ No newline at end of file diff --git a/src/utility/objaddr.rs b/src/utility/objaddr.rs index 42ad0a5..b2847e6 100644 --- a/src/utility/objaddr.rs +++ b/src/utility/objaddr.rs @@ -17,9 +17,13 @@ use crate::kernel::{synch::{ Semaphore, Lock }, thread::Thread}; /// calls. #[derive(PartialEq)] pub struct ObjAddr { + /// Id of the last added object last_id: i32, + /// List of [Semaphore] added in this struct. Each is keyed with a unique i32 id. semaphores: HashMap, + /// List of [Lock] added in this struct. Each is keyed with a unique i32 id. locks: HashMap, + /// List of threads known by this instance of ObjAddr (useful for managing lock ownership) threads: HashMap>>, }