diff --git a/Cargo.lock b/Cargo.lock index 30384b1..773eaea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7,7 +7,6 @@ name = "burritos" version = "0.1.0" dependencies = [ "cc", - "libc", ] [[package]] @@ -15,9 +14,3 @@ name = "cc" version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" - -[[package]] -name = "libc" -version = "0.2.140" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c" diff --git a/Cargo.toml b/Cargo.toml index 911c397..0606650 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,9 +3,6 @@ name = "burritos" version = "0.1.0" edition = "2021" -[dependencies] -libc = { version = "0.2.139", features = ["extra_traits"] } - [registries.crates-io] protocol = "sparse" diff --git a/src/kernel/elf.rs b/src/kernel/elf.rs deleted file mode 100644 index 84dce69..0000000 --- a/src/kernel/elf.rs +++ /dev/null @@ -1,143 +0,0 @@ -//Declaration des alias - -/* - Def ELF : - - The header file 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 */ diff --git a/src/kernel/exception.rs b/src/kernel/exception.rs index b020f6e..2c7f0d3 100644 --- a/src/kernel/exception.rs +++ b/src/kernel/exception.rs @@ -4,41 +4,109 @@ use crate::simulator::{machine::{ExceptionType, Machine}, error::{MachineOk, Mac use super::system::System; - +/// The halt system call. Stops Burritos. pub const SC_SHUTDOWN: u8 = 0; +/// The exit system call +/// +/// Ends the calling thread pub const SC_EXIT: u8 = 1; +/// The exec system call +/// +/// Creates a new process (thread+address space) pub const SC_EXEC: u8 = 2; +/// The join system call +/// +/// Wait for the thread idThread to finish pub const SC_JOIN: u8 = 3; +/// The create system call +/// +/// Create a new file in nachos file system pub const SC_CREATE: u8 = 4; +/// The open system call +/// +/// Opens a file and returns an openfile identifier pub const SC_OPEN: u8 = 5; +/// The read system call +/// +/// Read in a file or the console pub const SC_READ: u8 = 6; +/// The write system call +/// +/// Write in a file or at the console pub const SC_WRITE: u8 = 7; +/// Seek to a given position in an opened file pub const SC_SEEK: u8 = 8; +/// The close system call +/// +/// Close a file pub const SC_CLOSE: u8 = 9; +/// The newThread system call +/// +/// Create a new thread in the same address space pub const SC_NEW_THREAD: u8 = 10; -pub const SC_YIELD: u8 = 11; +/// The Yield System call +/// +/// Relinquish the CPU if any other thread is runnable +pub const SC_YIELD: u8 = 11; +/// the PError system call +/// +/// print the last error message pub const SC_PERROR: u8 = 12; +/// carry out P() on the semaphore pub const SC_P: u8 = 13; +/// carry out V() on the semaphore pub const SC_V: u8 = 14; -pub const SC_SEM_CREATE: u8 = 15 ; +/// create a semaphore and add it in g_objects_addrs +pub const SC_SEM_CREATE: u8 = 15; +/// destroy the semaphore corresponding to the id pub const SC_SEM_DESTROY: u8 = 16; -pub const SC_LOCK_CREATE: u8 = 17 ; -pub const SC_LOCK_DESTROY: u8 = 18 ; -pub const SC_LOCK_ACQUIRE: u8 = 19 ; -pub const SC_LOCK_RELEASE: u8 = 20 ; -pub const SC_COND_CREATE: u8 = 21 ; -pub const SC_COND_DESTROY: u8 = 22 ; -pub const SC_COND_WAIT: u8 = 23 ; +/// create a lock and add it to g_object_addrs +pub const SC_LOCK_CREATE: u8 = 17; +/// destroy the lock corresponding to the id +pub const SC_LOCK_DESTROY: u8 = 18; +/// carry out acquire() on the lock +pub const SC_LOCK_ACQUIRE: u8 = 19; +/// carry out release() on the lock +pub const SC_LOCK_RELEASE: u8 = 20; +/// create a condition variable and add it to g_object_addrs +pub const SC_COND_CREATE: u8 = 21; +/// destroy the condition variable corresponding to the id +pub const SC_COND_DESTROY: u8 = 22; +/// carry out wait() on the condition +pub const SC_COND_WAIT: u8 = 23; +/// carry out signal() on the condition pub const SC_COND_SIGNAL: u8 = 24; +/// carry out broadcast() on the condition pub const SC_COND_BROADCAST: u8 = 25; +/// the TtySend system call +/// +/// Sends some char by the serial line emulated pub const SC_TTY_SEND: u8 = 26; +/// the TtyReceive system call +/// +/// read some char on the serial line pub const SC_TTY_RECEIVE: u8 = 27; +/// the Mkdir system call +/// +/// make a new directory in the file system pub const SC_MKDIR: u8 = 28; +/// the Rmdir system call +/// +/// remove a directory from the file system pub const SC_RMDIR: u8 = 29; +/// The Remove system call +/// +/// Remove a file from the file system pub const SC_REMOVE: u8 = 30; +/// The FSList system call +/// +/// Lists all the file and directories in the filesystem pub const SC_FSLIST: u8 = 31; -pub const SC_SYS_TIME: u8 = 32 ; +// The systime system call. Gets the system time +pub const SC_SYS_TIME: u8 = 32; +/// Map a file in memory pub const SC_MMAP: u8 = 33; +/// Behaviour undefined and currently unused pub const SC_DEBUG: u8 = 34; pub const CONSOLE_OUTPUT: u8 = 1; @@ -47,15 +115,15 @@ pub const CONSOLE_OUTPUT: u8 = 1; pub fn call(exception: &ExceptionType, machine: &mut Machine, system: &mut System) -> Result { match exception { - ExceptionType::NoException => todo!(), + ExceptionType::NoException => Err("No Exception no yet implemented")?, ExceptionType::SyscallException => syscall(machine, system), - ExceptionType::PagefaultException => todo!(), - ExceptionType::ReadOnlyException => todo!(), - ExceptionType::BusErrorException => todo!(), - ExceptionType::AddressErrorException => todo!(), - ExceptionType::OverflowException => todo!(), - ExceptionType::IllegalInstrException => todo!(), - ExceptionType::NumExceptionTypes => todo!(), + ExceptionType::PagefaultException => Err("Page Fault Exception not yet implemented")?, + ExceptionType::ReadOnlyException => Err("Read Only Exception not yet implemented")?, + ExceptionType::BusErrorException => Err("Bus Error Exception not yet implemented")?, + ExceptionType::AddressErrorException => Err("AddressErrorException not yet implemented")?, + ExceptionType::OverflowException => Err("OverflowException not yet implemented")?, + ExceptionType::IllegalInstrException => Err("IllegalInstrException not yet implemented")?, + ExceptionType::NumExceptionTypes => Err("NumExceptionTypes not yet implemented")?, } } @@ -92,11 +160,10 @@ fn syscall(machine: &mut Machine, system: &mut System) -> Result todo!(), SC_CLOSE => todo!(), diff --git a/src/kernel/mod.rs b/src/kernel/mod.rs index 725760a..c87b037 100644 --- a/src/kernel/mod.rs +++ b/src/kernel/mod.rs @@ -2,7 +2,6 @@ pub mod process; pub mod thread; pub mod mgerror; pub mod system; -mod ucontext; mod synch; mod thread_manager; pub mod exception; \ No newline at end of file diff --git a/src/kernel/ucontext.rs b/src/kernel/ucontext.rs deleted file mode 100644 index 0c0aba6..0000000 --- a/src/kernel/ucontext.rs +++ /dev/null @@ -1,74 +0,0 @@ -#[cfg(not(target_os = "windows"))] -use std::mem::MaybeUninit; - -/// Safe wrapper for ucontext_t struct of linux-gnu libc -/// -/// setcontext and getcontext are unsafe function, this wrap unsafe libc functions -/// -/// This struct doesn't work on windows, because this struct is unavailable -/// -/// todo ucontext_t is not thread-safe (doesn't implements Send and Sync trait), and cannot be use in Threads as rust require var in Mutex (see system.rs) to have everything inside to implements thread-safe traits -#[derive(PartialEq)] -pub struct UContextT { - #[cfg(not(target_os = "windows"))] // struct non disponible sur la libc sur windows - pub buf: libc::ucontext_t, - pub stack_bottom: Vec -} - -#[cfg(not(target_os = "windows"))] -#[allow(unused)] // Temporary as we currently doesn't use this structure (this structure may disapear in a near future) -impl UContextT { - - pub fn new() -> Self { - let mut context = MaybeUninit::::uninit(); - unsafe { libc::getcontext(context.as_mut_ptr()) }; - Self { - buf: unsafe { context.assume_init() }, - stack_bottom: Vec::default(), - } - } - - /// Get user context and store it in variable pointed to by UCP. - /// - /// Use `man getcontext` for more informations - pub fn get_context(&mut self) -> i32 { - unsafe { - libc::getcontext(&mut self.buf) - } - } - - /// Set user context from information of variable pointed to by UCP. - /// - /// Use `man setcontext` for more informations - pub fn set_context(&mut self) -> i32 { - unsafe { - libc::setcontext(&self.buf) - } - } - - pub fn make_context(&mut self, func: extern "C" fn(), args: i32) { - unsafe { - libc::makecontext(&mut self.buf, func, args) - } - } - -} - -#[cfg(target_os = "windows")] -#[allow(unused)] -impl UContextT { - - pub fn new() -> Self { - Self { - stack_bottom: Vec::default() - } - } - - pub fn get_context(&mut self) { - // no op - } - - pub fn set_context(&mut self) { - // no op - } -} \ No newline at end of file diff --git a/src/simulator/machine.rs b/src/simulator/machine.rs index 166fbce..f9986e5 100644 --- a/src/simulator/machine.rs +++ b/src/simulator/machine.rs @@ -231,14 +231,12 @@ impl Machine { self.set_status(MachineStatus::SystemMode); // Handle the interruption match exception::call(&exception, self, system) { - Ok(MachineOk::Shutdown) => { + Ok(r) => { self.set_status(MachineStatus::UserMode); - return Ok(MachineOk::Shutdown); - } - _ => Err(format!("Syscall {:?} invalid or not implemented", exception))? - } // todo: return error if the syscall code is invalid - self.set_status(MachineStatus::UserMode); - Ok(MachineOk::Ok) + Ok(r) + }, + Err(e) => Err(format!("Syscall {:?} invalid or not implemented", e))? + } } /// Execute the instructions table of a machine putted in param @@ -249,7 +247,7 @@ impl Machine { pub fn run(&mut self, system: &mut System) { loop { match self.one_instruction(system) { - Ok(MachineOk::Ok) => println!("hello"), + Ok(MachineOk::Ok) => {}, Ok(MachineOk::Shutdown) => break, Err(e) => panic!("FATAL at pc {} -> {}", self.pc, e) }