Compare commits

...

40 Commits

Author SHA1 Message Date
Rativel Remi
b5ff4371e4 Merge branch 'toto' into 'main'
Added build.rs script

See merge request simpleos/burritos!28
2023-05-25 19:13:51 +00:00
Rémi Rativel
638f96336b merge branch documentation 2023-05-25 14:16:59 +02:00
Legot Quentin
905e647dda Merge branch 'doc' into 'main'
Add comments to thread_manager

See merge request simpleos/burritos!27
2023-05-24 21:20:51 +00:00
Quentin Legot
8a389ea9d3 Add comments 2023-05-24 22:00:16 +02:00
Rémi Rativel
e430a62c35 Kernel documentation. Still need to do thread.rs 2023-05-14 23:51:15 +02:00
François Autin
c2d51d72f1 Merge branch 'readmes' into 'main'
Updated project README.md

See merge request simpleos/burritos!26
2023-05-10 21:43:44 +00:00
François Autin
393917ae91
Updated project README.md 2023-05-10 17:04:38 +02:00
François Autin
f6af4f838b Merge branch 'indent-print' into 'main'
Indentation update

See merge request simpleos/burritos!25
2023-05-10 13:12:13 +00:00
François Autin
b8308a7261
Indentation update 2023-05-10 14:31:19 +02:00
François Autin
7860fc6a49 Merge branch 'lect-red' into 'main'
remplacement du lecteur rédacteur par les lock

See merge request simpleos/burritos!24
2023-05-10 11:03:07 +00:00
AmauryBrodu
f9de7f93bc remplacement du lecteur rédacteur par les lock 2023-05-10 12:51:12 +02:00
François Autin
569929098d Merge branch 'print_demo' into 'main'
Printing burritos logo instead of hello world

See merge request simpleos/burritos!23
2023-05-10 10:50:21 +00:00
François Autin
8929326505
Printing burritos logo instead of hello world 2023-05-10 12:49:20 +02:00
Brodu Amaury
a16d92ab7e Merge branch 'lect_red' into 'main'
ajout lecteur redacteur

See merge request simpleos/burritos!22
2023-05-10 10:32:29 +00:00
François Autin
df0930850a Merge branch 'clearing_make_file' into 'main'
Redirected error output from mv to /dev/null

See merge request simpleos/burritos!21
2023-05-10 10:27:24 +00:00
François Autin
0ba9a136cc
Redirected error output from mv to /dev/null 2023-05-10 12:26:42 +02:00
AmauryBrodu
ec2eea05ad ajout lecteur redacteur 2023-05-10 12:23:04 +02:00
François Autin
7f40538bc4 Merge branch 'makefile_demo' into 'main'
Updated makefile to add demos

See merge request simpleos/burritos!20
2023-05-10 09:20:19 +00:00
François Autin
20af365080
Updated makefile to add demos 2023-05-10 11:19:08 +02:00
Legot Quentin
01b1e90dba Merge branch 'fix-strings' into 'main'
Fix strings

See merge request simpleos/burritos!18
2023-05-10 07:11:04 +00:00
Rémi Rativel
2f38edee70 Module description 2023-05-10 08:02:25 +02:00
Rémi Rativel
c60aaa1aae Documentation for the simulator 2023-05-09 22:02:22 +02:00
Rémi Rativel
28200ebc04 small fix in mmu.rs documentation 2023-05-09 19:18:40 +02:00
Rémi Rativel
692c3bfa03 Documentation for mem_cmp.rs and mmu.rs modules 2023-05-09 19:15:56 +02:00
François Autin
c51bb694a5 Merge branch 'fix-nothing-to-run' into 'main'
Fixed nobody to run

See merge request simpleos/burritos!19
2023-05-09 16:15:43 +00:00
François Autin
8c61fd1aa6
Fixed nobody to run 2023-05-09 18:08:44 +02:00
François Autin
d35314bead Added missing current_thread assignment in test_lock_multiple 2023-05-05 00:30:06 +02:00
Quentin Legot
7b7d48c775 Try to fix double free 2023-05-05 00:30:06 +02:00
Rativel Remi
9dec9b041a Update userlib/sys.s 2023-05-05 00:30:06 +02:00
Quentin Legot
9bd0ef02aa Fix join not working on join.c 2023-05-05 00:30:06 +02:00
Quentin Legot
c6f5818059 try to implement join 2023-05-05 00:30:06 +02:00
François Autin
31f1e760e9 Fixed lock_release behaviour when multiple users of given lock 2023-05-05 00:30:06 +02:00
François Autin
f6195a9da0 Updated thread_manager module documentation 2023-05-05 00:30:06 +02:00
Rémi Rativel
5393c6e3f2 test lock for multiple threads
Signed-off-by: Rémi Rativel <remi.rativel@etudiant.univ-rennes1.fr>
2023-05-05 00:30:06 +02:00
François Autin
ff921117f7
Using direct link to git hosted logo for documentation 2023-04-21 14:55:07 +02:00
François Autin
ce4c7230f9
📝 Updated utility mod documentation 2023-04-21 14:50:55 +02:00
François Autin
33cbe77175
Fixed logo now showing up in doc 2023-04-21 14:46:06 +02:00
François Autin
052b950ca0
📝 Updated cfg.rs documentation 2023-04-21 14:42:07 +02:00
François Autin
f06f14354a
Added project logo to doc 2023-04-21 14:29:00 +02:00
François Autin
8732a6f0b7
Added build.rs script
- Executes make all
 - Moves the project logo to the documentation folder
2023-04-21 14:28:30 +02:00
23 changed files with 429 additions and 58 deletions

View File

@ -1,6 +1,13 @@
TOPDIR=.
include $(TOPDIR)/Makefile.config
#
# Demo vars
#
FLAGS=--offline -r --
CARGO=RUSTFLAGS=-Awarnings cargo run ${FLAGS}
all: dumps user_lib instruction_tests syscall
#
@ -22,10 +29,27 @@ syscall: user_lib
$(MAKE) build -C test/syscall_tests/
$(RM) test/syscall_tests/*.o
mkdir -p ${TOPDIR}/target/guac/
find . -name '*.guac' -exec mv {} ${TOPDIR}/target/guac/ \;
find . -name '*.guac' -exec mv {} ${TOPDIR}/target/guac/ 2> /dev/null \;
clean:
$(MAKE) clean -C userlib/
$(MAKE) clean -C test/
$(RM) -rf $(TOPDIR)/target
#
# Demo targets
#
halt: syscall
${CARGO} -x ./target/guac/halt.guac -d3
pc: syscall
${CARGO} -x ./target/guac/producteur_consommateur.guac -d2
matmult: syscall
${CARGO} -x ./target/guac/matmult.guac -d2
lock: syscall
${CARGO} -x ./target/guac/lock.guac -d2
prints: syscall
${CARGO} -x ./target/guac/prints.guac -d2

View File

@ -6,6 +6,76 @@ BurritOS (BurritOS Using Rust Really Improves The Operating System) is an educat
Based on [NachOS](https://homes.cs.washington.edu/~tom/nachos/) (Copyright (c) 1992-1993 The Regents of the University of California. All rights reserved.)
## Progress overview
![Progress overview](./assets/progress_overview.png)
Currently, the BurritOS project simulator contains a RISC-V processing unit supporting all 47 base instructions plus multiplication and 32bit floating point operations. RAM and the interrupt controller are also integrated. Both the memory management unit and the Disk are written but not tested nor integrated yet.
On the kernel side, synchronization primitives and scheduling logic are all implemented except for Conditions.
## Build instructions
To build in release mode:
```
$ cargo build -r
```
To build in development mode:
```
$ cargo build
```
The generated executable can then be found in the `./target` directory.
## Running BurritOS
*In the following examples, BurritOS is started by directly invoking its executable. However, replacing this direct invocation by `cargo run -- <PARAMETERS>` would garner the same result.*
As it stands, BurritOS does not include a virtual console nor a shell for dynamic user interaction. Thus, programs need to be manually loaded into the system memory. To perform this operation:
```
$ ./burritos --executable <PATH>
```
## Help
BurritOS provides a succinct manual. To display this manual:
```
$ ./burritos --help
```
## Documentation
Documentation for all components of the BurritOS project can be generated using the following command:
```
$ cargo doc
```
The generated web documentation can be found in the `./target/doc` directory.
## Tests
BurritOS is unit tested using the cargo provided testing framework. However, some tests, most notably the Machine tests, require access to a few files **which need to be generated first**.
To generate test files:
```
$ make all
```
Afterwards, tests can be run with:
```
$ cargo test
```
All make artifacts can be found in the `./target` directory.
## Authors
Amaury Brodu, Abdelmajid El Bahri, François Autin, Quentin Legot, Baptiste Meauze, Gabriel Moysan, Rémi Rativel, Samy Solhi

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

12
build.rs Normal file
View File

@ -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());
}

View File

@ -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}}};
@ -183,7 +188,7 @@ fn syscall(machine: &mut Machine, system: &mut System) -> Result<MachineOk, Mach
SC_LOCK_CREATE => sc_lock_create(machine, system),
SC_LOCK_DESTROY => sc_lock_destroy(machine, system),
SC_LOCK_ACQUIRE => sc_lock_acquire(machine, system),
SC_LOCK_RELEASE => todo!(),
SC_LOCK_RELEASE => sc_lock_release(machine, system),
SC_COND_CREATE => todo!(),
SC_COND_DESTROY => todo!(),
SC_COND_WAIT => todo!(),
@ -292,6 +297,7 @@ fn sc_new_thread(machine: &mut Machine, system: &mut System) -> Result<MachineOk
} else {
return Err("Process owner of current thread is none")?;
}
}
fn sc_join(machine: &mut Machine, system: &mut System) -> Result<MachineOk, MachineError> {

View File

@ -1,3 +1,11 @@
//! # Error Code
//!
//! This module enumerate the possibles error code who could get in a function
//!
//! **Basic Usage:*
//!
//! Result<YourSuccessStruct, **ErrorCode**
#![allow(unused, clippy::missing_docs_in_private_items)]
/// Error enum, use it with Result<YourSucessStruct, **ErrorCode**>
pub enum ErrorCode {

View File

@ -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;

View File

@ -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<Rc<RefCell<Thread>>>,
}
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) =>

View File

@ -1,3 +1,6 @@
//! # Thread
//!
//!
use std::{rc::Rc, cell::RefCell};
use super::{process::Process, thread_manager::ThreadRef};

View File

@ -119,6 +119,9 @@ pub struct ThreadManager {
obj_addrs: ObjAddr,
/// If true, enables debug mode
debug: bool,
/// Temporary field, to be removed when virtual memory will be available to use.
///
/// A value to know where the next starting thread should have its stack pointer
sp_max: u64,
}
@ -136,19 +139,19 @@ impl ThreadManager {
}
}
/// Mark a thread as aready, but not necessarily running yet.
/// Mark `thread` as ready, but not necessarily running yet.
///
/// Put it in the ready list, for later scheduling onto the CPU.
///
/// ## Pamameter
///
/// **thread** is the thread to be put on the read list
/// **thread** is the thread to be put on the ready list
pub fn ready_to_run(&mut self, thread: ThreadRef) {
self.ready_list.push(thread);
}
/// Return the next thread to be scheduled onto the CPU.
/// If there are no ready threads, return Option::None
/// If there are no ready threads, return `Option::None`
///
/// Thread is removed from the ready list.
///
@ -157,12 +160,12 @@ impl ThreadManager {
self.ready_list.pop()
}
/// Dispatch the CPU to next_thread. Save the state of the old thread
/// Dispatch the CPU to `next_thread`. Save the state of the old thread
/// and load the state of the new thread.
///
/// We assume the state of the previously running thread has already been changed from running to blocked or ready.
///
/// Global variable g_current_thread become next_thread
/// Variable `g_current_thread` become next_thread
///
/// ## Parameter
///
@ -187,6 +190,14 @@ impl ThreadManager {
}
/// Start a thread, attaching it to a process
///
/// ## Parameter
///
/// **thread** thread to start
/// **owner** process owner of thread (after the execution of this method)
/// **func_pc** pc the thread
/// **sp_loc** stack pointer of the thread, to remove (or move) when mmu will be completed
/// **argument** value to be place on register[10]
pub fn start_thread(&mut self, thread: ThreadRef, owner: Rc<RefCell<Process>>, func_pc: u64, sp_loc: u64, argument: i64) {
self.debug(format!("starting thread \"{}\"", thread.borrow().get_name()));
@ -201,6 +212,11 @@ impl ThreadManager {
}
/// Wait for another thread to finish its execution
///
/// If the thread you want to wait doesn't exist (isn't alive), execution will resume.
/// Otherwise, CPU is dispatch to next alive thread if any.
///
/// When the thread you want to join finish, it place the waiting thread (self) in ready list
pub fn thread_join(&mut self, machine: &mut Machine, waiter: ThreadRef, waiting_for: ThreadRef) {
let waiting_for = Rc::clone(&waiting_for);
if self.get_g_alive().contains(&waiting_for) {
@ -211,10 +227,19 @@ impl ThreadManager {
/// Relinquish the CPU if any other thread is runnable.
///
/// Cannot use yield as a function name -> reserved name in rust
/// 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.
///
/// Interruptions are disabled during the process, so all the process of looking for a next thread and switching to it is atomic,
/// and is place at its old status at the end of the method.
///
/// Cannot use `yield` as a function name -> reserved name in rust
///
/// ## Parameters
///
/// **machine** RISC-V simulator
/// **thread** current thread to be relinquish
/// **is_ready** true if **thread** should be readded to ready_to_run list, false otherwise. Typically false when joining per example
pub fn thread_yield(&mut self, machine: &mut Machine, thread: ThreadRef, is_ready: bool) {
let old_status = machine.interrupt.set_status(crate::simulator::interrupt::InterruptStatus::InterruptOff);
@ -231,7 +256,16 @@ impl ThreadManager {
machine.interrupt.set_status(old_status);
}
/// Put the thread to sleep and relinquish the processor
/// Put the thread to sleep and relinquish the processor because the current thread is blocked (Semaphore, Lock, Condition) or because it finished its execution
///
/// Another thread will eventually wake it up and put it back to ready list after it has been unblocked.
///
/// Behavior now: At the moment, disk isn't fully develop and not integrated to burritos, so if there's no ready thread, then we stop the OS.
///
/// Behaviour in the future: If there are no threads on the ready list, that means there is no thread to run,
/// we assume this is because at least one thread is waiting for I/O [`interrupt`](crate::simulator::interrupt::Interrupt) (the only reason a new thread can become ready at this point).
///
/// We also assume interruption are already disabled, becuase it's called from a synchronization routine for interrupt should be disabled.
pub fn thread_sleep(&mut self, machine: &mut Machine, thread: ThreadRef) {
debug_assert_eq!(Option::Some(Rc::clone(&thread)), self.g_current_thread);
debug_assert_eq!(machine.interrupt.get_status(), InterruptStatus::InterruptOff);
@ -252,6 +286,12 @@ impl ThreadManager {
}
/// Finish the execution of the thread and prepare its deallocation
///
/// Called by the thread itself when it finish its execution ([`Exit`](super::exception::SC_EXIT) exception).
///
/// We remove the thread from the alive list, and rustc deallocate the thread itself(behaviour different than Nachos)
///
/// Interruption are disabled to assume atomicity.
pub fn thread_finish(&mut self, machine: &mut Machine, thread: ThreadRef, exit_code: i64) {
let old_status = machine.interrupt.set_status(InterruptStatus::InterruptOff);
assert!(self.g_alive.remove(Rc::clone(&thread)));
@ -265,6 +305,8 @@ impl ThreadManager {
}
/// Save the CPU state of a user program on a context switch.
///
/// Save PC and registers
pub fn thread_save_processor_state(&mut self, machine: &mut Machine, thread: ThreadRef) {
let mut t = thread.borrow_mut();
for i in 0..NUM_INT_REGS {
@ -277,6 +319,8 @@ impl ThreadManager {
}
/// Restore the CPU state of a user program on a context switch.
///
/// Restore PC and registers
pub fn thread_restore_processor_state(&self, machine: &mut Machine, thread: ThreadRef) {
let t: Ref<_> = thread.borrow();
for i in 0..NUM_INT_REGS {
@ -371,7 +415,9 @@ impl ThreadManager {
Ok(MachineOk::Ok)
}
/// Wake up a waiter if necessary, or release it if no thread is waiting.
/// Release lock hold by current thread and wake up a waiter if necessary, placing it on ready list, this thread now hold the lock.
///
/// If no thread is waiting for the lock, the lock is released
pub fn lock_release(&mut self, id: i32, machine: &mut Machine) -> Result<MachineOk, MachineError> {
let old_status = machine.interrupt.set_status(InterruptStatus::InterruptOff);
let current_thread = match self.get_g_current_thread() {
@ -402,12 +448,12 @@ impl ThreadManager {
Ok(MachineOk::Ok)
}
/// Currently running thread
/// Return currently running thread
pub fn get_g_current_thread(&mut self) -> &Option<ThreadRef> {
&self.g_current_thread
}
/// List of alive threads
/// Return list of alive threads
pub fn get_g_alive(&mut self) -> &mut List<ThreadRef> {
&mut self.g_alive
}

View File

@ -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));

View File

@ -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
}

View File

@ -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 <https://en.wikipedia.org/wiki/Executable_and_Linkable_Format#File_header> 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

View File

@ -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

View File

@ -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,

View File

@ -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;

View File

@ -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<PageTableEntry>
}
impl TranslationTable {
/// TranslationTable constructor
///
/// ### Return
/// TranslationTable with an empty Vector
pub fn create() -> TranslationTable {
let mut tmp_vec : Vec<PageTableEntry> = Vec::new();

View File

@ -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<String>`], each entry containing a valid
/// line from the input file.
fn filter_garbage<R: std::io::Read>(reader: BufReader<R>) -> Vec<String> {
reader.lines()
.map(|l| l.unwrap())
@ -111,11 +115,13 @@ fn filter_garbage<R: std::io::Read>(reader: BufReader<R>) -> Vec<String> {
.collect()
}
/// Inserts user settings into setting map
/// Adds a <K, V> 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::<u64>().unwrap_or(0);
let setting = str::parse::<u64>(setting).unwrap_or(0);
settings_map.insert(key, setting);
settings_map
}

View File

@ -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;

View File

@ -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<i32, Semaphore>,
/// List of [Lock] added in this struct. Each is keyed with a unique i32 id.
locks: HashMap<i32, Lock>,
/// List of threads known by this instance of ObjAddr (useful for managing lock ownership)
threads: HashMap<i32, Rc<RefCell<Thread>>>,
}

View File

@ -1,4 +1,4 @@
PROGRAMS = halt.guac prints.guac producteur_consommateur.guac join.guac matmult.guac
PROGRAMS = halt.guac prints.guac producteur_consommateur.guac lock.guac join.guac matmult.guac
TOPDIR = ../..
include $(TOPDIR)/Makefile.rules

29
test/syscall_tests/lock.c Normal file
View File

@ -0,0 +1,29 @@
#include "userlib/syscall.h"
#include "userlib/libnachos.h"
LockId mutex;
int glob_int = 0;
void increment(void){
LockAcquire(mutex);
glob_int++;
LockRelease(mutex);
}
void counter(int n){
for (int i = 0; i < 50; i++){
increment();
}
}
int main(void){
mutex = LockCreate("Lock_debug");
ThreadId th1 = threadCreate("Thread1", (VoidNoArgFunctionPtr) counter);
ThreadId th2 = threadCreate("Thread2",(VoidNoArgFunctionPtr) counter);
Join(th1);
Join(th2);
Exit(glob_int);
return 0;
}

View File

@ -2,10 +2,53 @@
#include "userlib/libnachos.h"
int main() {
n_printf("Hello World 1\n");
n_printf("Hello World 2\n");
n_printf("Hello World 3\n");
n_printf("Hello World 4\n");
n_printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
n_printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&##BBGGGPPGGGBB##&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
n_printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&#G5J?!~^::............::^~!?J5G#&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
n_printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@&B5?!^:....:^^~!!7777??7777!!~~^::...:^!JPB&@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
n_printf("@@@@@@@@@@@@@@@@@@@@@@@@@B57^....^~!?JJYYY5555555555555555Y5PGP57~::..:^75B@@@@@@@@@@@@@@@@@@@@@@@@@\n");
n_printf("@@@@@@@@@@@@@@@@@@@@@&G?~. .:~7?JY55555YYYYYYYYYYYYYYYYY5PB##BPY???7!~^:..:~JG&@@@@@@@@@@@@@@@@@@@@@\n");
n_printf("@@@@@@@@@@@@@@@@@@@BJ~. .^!?Y5555YYYYYYYYYYYYYYYYYYYY5PB##B5J?77???????7!~^:.:~JB@@@@@@@@@@@@@@@@@@@\n");
n_printf("@@@@@@@@@@@@@@@@&P!. .^!JY55YYYYYYYYYYYYYYYYYYYYYY5PB##B5J?77??????????????7~^:.:!P&@@@@@@@@@@@@@@@@\n");
n_printf("@@@@@@@@@@@@@@&Y^..:~?Y55YYYYYYYYYYYYYYYYYYYYYY5PB##B5J?77????????????????????7~:.:~5&@@@@@@@@@@@@@@\n");
n_printf("@@@@@@@@@@@@&5^..:!J55YYYYYYYYYYYYYYYYYYYYYY5PB##B5J?77?????????????????????????7~^::~5@@@@@@@@@@@@@\n");
n_printf("@@@@@@@@@@@G~..:!Y55YYYYYYYYYYYYYYYYYYYYY5PB##B5J?77??????????????????????????????7~:::!B@@@@@@@@@@@\n");
n_printf("@@@@@@@@@&J...~J55YYYYYYYYYYYYYYYYYYYY5PB##B5J?77??????????????????????????????777?Y57:::J&@@@@@@@@@\n");
n_printf("@@@@@@@@#!..:7Y5YYYYYYYYYYYYYYYYYYY5PB##B5J?77??????????????????????????????777?YPB##G?^::7#@@@@@@@@\n");
n_printf("@@@@@@@G^..^J5YYYYYYYYYYYYYYYYYY5PB##B5J?77??????????????????????????????777?YPB##GP5Y5J~::~B@@@@@@@\n");
n_printf("@@@@@@G^..^Y5YYYYYYYYYYYYYYYY5PB##B5J?77??????????????????????????????777?YPB##GP55Y5555Y~::^B@@@@@@\n");
n_printf("@@@@@B^..^Y5YYYYYYYYYYYYYY5PB##B5J?77??????????????????????????????777?YPB##GP5YYYY555555Y~::~B@@@@@\n");
n_printf("@@@@&!..^J5YYYYYYYYYYYY5PB##B5J?77??????????????????????????????777?YPB#BGPYYYYYY555555555Y~::7&@@@@\n");
n_printf("@@@@J..:?5YYYYYYYYYY5PB##B5J?77??????????????????????????????777?YPB#BG5YYYYYYY55YY55555555J^::Y@@@@\n");
n_printf("@@@B:..~5YYYYYYYY5PB##G5J?77??????????????????????????????777?YPB#BG5YYYYYYYY5YYY55555555555!::^#@@@\n");
n_printf("@@@?..:JYYYYYY5PB##G5J?77??????????????????????????????777?YPB#BG5YYYYYYYYYYYYY55YY555555555Y^::J@@@\n");
n_printf("@@&^..~YYYY5PB##G5J?77??????????????????????????????777?YPB#BG5YYYYYYYYYYYYYYYYYY5555Y5555555!::~&@@\n");
n_printf("@@G:..7Y5PB##G5J?77??????????????????????????????777?YPB#BG5YJYYYYYYYYYYYYYYYYY55YYY555555555?::^B@@\n");
n_printf("@@5:..YB##G5J?77??????????????????????????????777?YPB#BG5JJJYYYJYYYYYYYYYYYYYY5YY5555Y5555555J:^^P@@\n");
n_printf("@@5:..PB5J?77??????????????????????????????777?YGB#BG5JJJYYJYYYYYYYYYYYYYYYYYYY55Y55555555555J:^^5@@\n");
n_printf("@@5:..7?77??????????????????????????????777?YPB#BG5JJJJJJJJYYYYYYYYYYYYYYYYYYY5YY5Y5555555555J:^^P@@\n");
n_printf("@@G:..~??????????????????????????????777?YGB#BPYJJJJJJJJJJJYYYYYYYYYYYYYYYYYYYY5YY55555555555?:^^B@@\n");
n_printf("@@&^..^???????????????????????????777?YGB#BPYJ?JJJJJJJJJJJYYJYYYYYYYYYYYYYYYYY5YY5Y5555555555!^:~@@@\n");
n_printf("@@@?.::7???????????????????????777?YGB#BPYJ???JJJJJJJJJJJJJYYYYYYYYYYYYYYYYYYYYYYY5555555555Y^^:J@@@\n");
n_printf("@@@#:..^????????????????????777?YG##BPYJ????JJJJJJJJJJJJJJYJJYYYYYYYYYYYYYYYYY5YYYY555555555!^^^#@@@\n");
n_printf("@@@@J.::!????????????????777?YG##BPY???????JJJJJJJJJJJJJJJJYYYYYYYYYYYYYYYYYY5YYY5555555555J^^:Y@@@@\n");
n_printf("@@@@&!..:7????????????777?YGB#BPJ????????????JJJJJJJJJJJJYYJJYYYYYYYYYYYYYYYYYY55YY5555555Y~::7&@@@@\n");
n_printf("@@@@@B^.:^7????????777?YGB#BPJ?7???????????JJJ?JJJJJJJJJJJJYYYYJYYYYYYYYYYYYYYYYY5555Y555Y~^:~B@@@@@\n");
n_printf("@@@@@@G^.:^7????777?YGB#BPJ?7????????????????JJJJJJJJJJJJYYJJYYYYYYYYYYYYYYYYYY55YYY5555Y~::~B@@@@@@\n");
n_printf("@@@@@@@B^.:^7?77?YGB#BPJ?77??7?????????????JJJ?JJJJJJJJJJJJYYYYJYYYYYYYYYYYYYYYYY5555Y5J~::~B@@@@@@@\n");
n_printf("@@@@@@@@#!..:!YG##BPJ?77?????????????????????JJJJJJJJJJJJYYJYYYYYYYYYYYYYYYYYYY55YYY55?^::7#@@@@@@@@\n");
n_printf("@@@@@@@@@&J:.:7PPY?77???7????7??????????????JJ?JJJJJJJJJJJJYYYYJYYYYYYYYYYYYYY5YY555J!^:^Y&@@@@@@@@@\n");
n_printf("@@@@@@@@@@@G!..:~7?????????????????????????JJJJJJJJJJJJJJYYJYYYYYYYYYYYYYYYYYYY555Y7^::7G@@@@@@@@@@@\n");
n_printf("@@@@@@@@@@@@@5~..:~7????????????????????????JJJJJJJJJJJJJJJYJYYYYYYYYYYYYYYYYY5YY7^::~5@@@@@@@@@@@@@\n");
n_printf("@@@@@@@@@@@@@@&Y~..:~7?????????????????????JJJJJJJJJJJJJJJJYYYYYYYYYYYYYYYYY5YJ!^::!5&@@@@@@@@@@@@@@\n");
n_printf("@@@@@@@@@@@@@@@@&P!:.:^~7???????????????????JJJJJJJJJJJJJJJJJYYYYYYYYYYYYYYJ7~::^7P&@@@@@@@@@@@@@@@@\n");
n_printf("@@@@@@@@@@@@@@@@@@@BJ~:.:^~77??????????????JJ?JJJJJJJJJJJJJYYYYYYYYYYYYYJ7~^::!YB@@@@@@@@@@@@@@@@@@@\n");
n_printf("@@@@@@@@@@@@@@@@@@@@@&GJ~:.::~!!7????????????JJJJJJJJJJJJJYJJYYYYYYJ?7!^::^!JG&@@@@@@@@@@@@@@@@@@@@@\n");
n_printf("@@@@@@@@@@@@@@@@@@@@@@@@@B5?~::::^~~!7????JJJJJJJJJJJJYYJJJJJJ?77!~^::^~?5B@@@@@@@@@@@@@@@@@@@@@@@@@\n");
n_printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@&BPJ7~^:::::^~~~!!77777777!!!~~^^::::^~7JPB&@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
n_printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&#G5Y?7!~^^::::::::::::^~~!7JYPG#&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
n_printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&&##BGGGGGGGBB##&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
n_printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
Shutdown();
return 0;
}