Merge remote-tracking branch 'origin/thread_scheduler' into thread_scheduler

This commit is contained in:
Rémi Rativel 2023-03-08 15:45:47 +01:00
commit d03bb47131
5 changed files with 242 additions and 29 deletions

7
Cargo.lock generated
View File

@ -6,16 +6,9 @@ version = 3
name = "burritos" name = "burritos"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"lazy_static",
"libc", "libc",
] ]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.139" version = "0.2.139"

View File

@ -4,5 +4,4 @@ version = "0.1.0"
edition = "2021" edition = "2021"
[dependencies] [dependencies]
lazy_static = "1.4.0"
libc = { version = "0.2.139", features = ["extra_traits"] } libc = { version = "0.2.139", features = ["extra_traits"] }

143
src/kernel/elf.rs Normal file
View File

@ -0,0 +1,143 @@
//Declaration des alias
/*
Def ELF :
The header file <elf.h> defines the format of ELF executable binary
files. Amongst these files are normal executable files, relocatable
object files, core files and shared libraries.
An executable file using the ELF file format consists of an ELF header,
followed by a program header table or a section header table, or both.
The ELF header is always at offset zero of the file. The program
header table and the section header table's offset in the file are
defined in the ELF header. The two tables describe the rest of the
particularities of the file
*/
/* Type for a 16-bit quantity. */
type Elf32_Half = u16;
type Elf64_Half = u16;
/* Types for signed and unsigned 32-bit quantities. */
type Elf32_Word = u32;
type Elf32_Sword = i32;
type Elf64_Word = u32;
type Elf64_Sword = i32;
/* Types for signed and unsigned 64-bit quantities. */
type Elf32_Xword = u64;
type Elf32_Sxword = i64;
type Elf64_Xword = u64;
type Elf64_Sxword = i64;
/* Type of addresses. */
type Elf32_Addr = u32;
type Elf64_Addr = u64;
/* Type of file offsets. */
type Elf32_Off = u32;
type Elf64_Off = u64;
//role de ce truc ?
const EI_NIDENT : u8 = 16;
//ELF file header 32 bits
struct Elf32Ehdr{
e_ident : [u8;EI_NIDENT],//16 octects décrivant comment le fichier doit etre parsé
//e_ident must starts with magice number : 0x 7f 45 4c 46
e_type : Elf32_Half,//type of the file
e_machine : Elf32_Half,//type architecture machine
e_version : Elf32_Word,//always 1
e_entry : Elf32_Addr,//entry point @ for executable
e_phoff : Elf32_Off,//Offset of the program header table
e_shoff : Elf32_Off,//Offset of the section header table
e_flags : Elf32_Word,//des flags ?
e_ehsize : Elf32_Half,//size of this (the header), redundant
e_phentsize : Elf32_Half,//size per program header
e_phnum : Elf32_Half,//number of program header
e_shentsize : Elf32_Half,//size per section header
e_shnum : Elf32_Half,//number of section header
e_shstrndx : Elf32_Half//section header string table index
}
//ELF file header 64 bits
//les champs ont le meme rôle que dans le header 32 bits
struct Elf64Ehdr{
e_ident : [u8;EI_NIDENT],
e_type : Elf64_Half,
e_machine : Elf64_Half,
e_version : Elf64_Word,
e_entry : Elf64_Addr,
e_phoff : Elf64_Off,
e_shoff : Elf64_Off,
e_flags : Elf64_Word,
e_ehsize : Elf64_Half,
e_phentsize : Elf64_Half,
e_phnum : Elf64_Half,
e_shentsize : Elf64_Half,
e_shnum : Elf64_Half,
e_shstrndx : Elf64_Half
}
/* e_ident offsets */
const EI_MAG0 : u32 = 0;
const EI_MAG1 : u32 = 1;
const EI_MAG2 : u32 = 2;
const EI_MAG3 : u32 = 3;
const EI_CLASS : u32 = 4;
const EI_DATA : u32 = 5;
const EI_VERSION : u32 = 6;
const EI_PAD : u32 = 7;
/* e_ident[EI_CLASS] */
const ELFCLASSNONE : u32 = 0;
const ELFCLASS32 : u32 = 1;
const ELFCLASS64 : u32 = 2;
/* e_ident[EI_DATA] */
const ELFDATANONE : u32 = 0;
const ELFDATA2LSB : u32 = 1;
const ELFDATA2MSB : u32 = 2;
/* e_type */
const ET_NONE : u32 = 0; /* No file type */
const ET_REL : u32 = 1; /* Relocatable file */
const ET_EXEC : u32 = 2; /* Executable file */
const ET_DYN : u32 = 3; /* Shared object file */
const ET_CORE : u32 = 4; /* Core file */
const ET_LOPROC : u32 = 0xff00; /* Processor-specific */
const ET_HIPROC : u32 = 0xffff; /* Processor-specific */
/* e_machine */
const EM_NONE : u32 = 0; /* No machine */
const EM_M32 : u32 = 1; /* AT&T WE 32100 */
const EM_SPARC : u32 = 2; /* SPARC */
const EM_386 : u32 = 3; /* Intel 80386 */
const EM_68K : u32 = 4; /* Motorola 68000 */
const EM_88K : u32 = 5; /* Motorola 88000 */
const EM_860 : u32 = 7; /* Intel 80860 */
const EM_MIPS : u32 = 8; /* MIPS R3000 */
const EM_RISC : u32 = 243; /* RISCV */
/* e_version */
const EV_NONE : u32 = 0; /* invalid version */
const EV_CURRENT : u32 = 1; /* current version */

View File

@ -1,19 +1,98 @@
use std::{sync::{RwLock, Arc}}; use std::rc::Rc;
use crate::{
kernel::{
thread::Thread,
scheduler::Scheduler
},
utility::list::List,
simulator::machine::Machine
};
use lazy_static::lazy_static; /// # System
///
use crate::{kernel::{thread::Thread, scheduler::Scheduler}, utility::list::List, simulator::machine::Machine}; /// This structure represents the state of the threads running on the operating system.
/// It contains references to the following:
extern crate lazy_static; ///
/// - The simulated machine
lazy_static! { /// - The current running thread
pub static ref G_MACHINE: RwLock<Machine> = RwLock::new(Machine::_init_machine()); /// - The list of active threads
pub static ref G_CURRENT_THREAD: RwLock<Option<Thread>> = RwLock::new(Option::None); /// - The thread to be destroyed next
pub static ref G_THREAD_TO_BE_DESTROYED: RwLock<Option<Thread>> = RwLock::new(Option::None); /// - The scheduler which acts upon these threads
pub static ref G_ALIVE: RwLock<List<Arc<Thread>>> = RwLock::new(List::new()); pub struct System {
pub static ref G_SCHEDULER: RwLock<Scheduler> = RwLock::new(Scheduler::new()); g_machine: Machine,
g_current_thread: Option<Thread>,
g_thread_to_be_destroyed: Option<Thread>,
g_alive: List<Rc<Thread>>,
g_scheduler: Scheduler
} }
impl System {
/// System constructor
pub fn new(machine: Machine, scheduler: Scheduler) -> Self {
Self {
g_machine: machine,
g_current_thread: None,
g_thread_to_be_destroyed: None,
g_alive: List::new(),
g_scheduler: scheduler
}
}
// GETTERS
/// Returns the Machine
///
/// Useful to access RAM, devices, ...
pub fn get_g_machine(&mut self) -> &mut Machine {
&mut self.g_machine
}
/// Currently running thread
pub fn get_g_current_thread(&mut self) -> &mut Option<Thread> {
&mut self.g_current_thread
}
/// Thread to be destroyed by [...]
///
/// TODO: Finish the comment with the relevant value
pub fn get_g_thread_to_be_destroyed(&mut self) -> &mut Option<Thread> {
&mut self.g_thread_to_be_destroyed
}
/// List of alive threads
pub fn get_g_alive(&mut self) -> &mut List<Rc<Thread>> {
&mut self.g_alive
}
/// Current scheduler
pub fn g_scheduler(&mut self) -> &mut Scheduler {
&mut self.g_scheduler
}
// Setters
/// Assign a machine to the system
pub fn set_g_machine(&mut self, machine: Machine) {
self.g_machine = machine
}
/// Set currently running thread
pub fn set_g_current_thread(&mut self, thread: Option<Thread>) {
self.g_current_thread = thread
}
/// Set thread to be destroyed next
pub fn set_g_thread_to_be_destroyed(&mut self, thread: Option<Thread>) {
self.g_thread_to_be_destroyed = thread
}
/// Set Scheduler which will manage the threads
pub fn set_g_scheduler(&mut self, scheduler: Scheduler) {
self.g_scheduler = scheduler
}
}
#[derive(PartialEq)] #[derive(PartialEq)]
pub enum ObjectType { pub enum ObjectType {

View File

@ -2,15 +2,14 @@ mod simulator;
mod kernel; mod kernel;
pub mod utility; pub mod utility;
use kernel::{
scheduler::Scheduler,
system::System
};
use simulator::machine::Machine; use simulator::machine::Machine;
fn main() { fn main() {
let mut m = Machine::_init_machine(); let machine = Machine::_init_machine();
m.main_memory[4] = 43; let scheduler = Scheduler::new();
m.main_memory[5] = 150; let system = System::new(machine, scheduler);
let a : u8 = 128;
let b : i8 = a as i8;
let c : u8 = b as u8;
println!("aaa {c}");
println!("read_memory : {}", Machine::read_memory(&mut m, 2, 4));
} }