Add a bin loader
This commit is contained in:
parent
a223c14f36
commit
08ba0154f7
@ -1,4 +1,4 @@
|
|||||||
mod process;
|
pub mod process;
|
||||||
pub mod thread;
|
pub mod thread;
|
||||||
pub mod mgerror;
|
pub mod mgerror;
|
||||||
pub mod system;
|
pub mod system;
|
||||||
|
24
src/main.rs
24
src/main.rs
@ -13,10 +13,28 @@ mod kernel;
|
|||||||
/// module containing useful tools which can be use in most part of the OS to ease the development of the OS
|
/// module containing useful tools which can be use in most part of the OS to ease the development of the OS
|
||||||
pub mod utility;
|
pub mod utility;
|
||||||
|
|
||||||
|
use std::{rc::Rc, cell::RefCell};
|
||||||
|
|
||||||
use kernel::system::System;
|
use kernel::system::System;
|
||||||
use simulator::machine::Machine;
|
use simulator::{machine::Machine, loader};
|
||||||
|
|
||||||
|
use crate::kernel::{thread::Thread, process::Process};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let machine = Machine::init_machine();
|
let mut machine = Machine::init_machine();
|
||||||
let system = System::default();
|
loader::load("test.o", &mut machine, 0).expect("IO Error");
|
||||||
|
let system = &mut System::default();
|
||||||
|
let thread1 = Thread::new("th1");
|
||||||
|
let thread1 = Rc::new(RefCell::new(thread1));
|
||||||
|
system.get_thread_manager().get_g_alive().push(Rc::clone(&thread1));
|
||||||
|
let owner = Process { num_thread: 0 };
|
||||||
|
system.get_thread_manager().start_thread(Rc::clone(&thread1), owner, 0 as i64, 0);
|
||||||
|
debug_assert_eq!(thread1.borrow_mut().thread_context.pc, 0 as i64);
|
||||||
|
let to_run = system.get_thread_manager().find_next_to_run().unwrap();
|
||||||
|
debug_assert_eq!(to_run, Rc::clone(&thread1));
|
||||||
|
debug_assert!(system.get_thread_manager().get_g_alive().contains(&Rc::clone(&thread1)));
|
||||||
|
system.get_thread_manager().switch_to(&mut machine, Rc::clone(&to_run));
|
||||||
|
|
||||||
|
machine.run();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ use crate::Machine;
|
|||||||
use std::fs;
|
use std::fs;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::io::BufRead;
|
use std::io::BufRead;
|
||||||
|
use std::io::Read;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -15,6 +16,7 @@ use std::io::BufRead;
|
|||||||
///
|
///
|
||||||
/// - **path** the path of the file to load
|
/// - **path** the path of the file to load
|
||||||
/// - **size** the number of bytes to write (1, 2, 4 or 8)
|
/// - **size** the number of bytes to write (1, 2, 4 or 8)
|
||||||
|
#[deprecated]
|
||||||
pub fn _load(path : &str, instruction_size: i32) -> Machine {
|
pub fn _load(path : &str, instruction_size: i32) -> Machine {
|
||||||
let file = fs::File::open(path).expect("Wrong filename");
|
let file = fs::File::open(path).expect("Wrong filename");
|
||||||
let reader = io::BufReader::new(file);
|
let reader = io::BufReader::new(file);
|
||||||
@ -31,4 +33,33 @@ pub fn _load(path : &str, instruction_size: i32) -> Machine {
|
|||||||
}
|
}
|
||||||
println!("{:x}", Machine::read_memory(& mut machine, 4, 0));
|
println!("{:x}", Machine::read_memory(& mut machine, 4, 0));
|
||||||
machine
|
machine
|
||||||
|
}
|
||||||
|
|
||||||
|
/// load a 32-bits binary file into the machine
|
||||||
|
///
|
||||||
|
/// ### Parameters
|
||||||
|
///
|
||||||
|
/// - **path** path of the file to load
|
||||||
|
/// - **machine** the machine where the bin file will be loaded
|
||||||
|
/// - **start_index** at which index of machine memory you want to start to load the program
|
||||||
|
///
|
||||||
|
/// Returns in a Result any io error
|
||||||
|
pub fn load(path: &str, machine: &mut Machine, start_index: usize) -> Result<(), std::io::Error> {
|
||||||
|
let mut file = fs::File::open(path)?;
|
||||||
|
let mut instructions: Vec<u32> = Default::default();
|
||||||
|
loop {
|
||||||
|
let mut buf: [u8; 4] = [0; 4];
|
||||||
|
let res = file.read(&mut buf)?;
|
||||||
|
if res == 0 {
|
||||||
|
break; // eof
|
||||||
|
} else {
|
||||||
|
instructions.push(u32::from_le_bytes(buf));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for i in 0..instructions.len() {
|
||||||
|
machine.write_memory(4, 4 * i + start_index, instructions[i] as u64);
|
||||||
|
}
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
println!("{:04x?}", instructions); // only print loaded program in debug build
|
||||||
|
Ok(())
|
||||||
}
|
}
|
@ -146,7 +146,7 @@ impl Machine {
|
|||||||
/// - **machine** which contains the main memory
|
/// - **machine** which contains the main memory
|
||||||
/// - **size** the number of bytes to read (1, 2, 4, 8)
|
/// - **size** the number of bytes to read (1, 2, 4, 8)
|
||||||
/// - **address** in the memory to read
|
/// - **address** in the memory to read
|
||||||
pub fn read_memory(machine : &mut Machine, size : i32, address : usize) -> u64 {
|
pub fn read_memory(&mut self, size : i32, address : usize) -> u64 {
|
||||||
if ![1, 2, 4, 8].contains(&size) {
|
if ![1, 2, 4, 8].contains(&size) {
|
||||||
panic!("ERROR read_memory : wrong size parameter {size}, must be (1, 2, 4 or 8)");
|
panic!("ERROR read_memory : wrong size parameter {size}, must be (1, 2, 4 or 8)");
|
||||||
}
|
}
|
||||||
@ -154,7 +154,7 @@ impl Machine {
|
|||||||
let mut ret: u64 = 0;
|
let mut ret: u64 = 0;
|
||||||
for i in 0..size {
|
for i in 0..size {
|
||||||
ret <<= 8;
|
ret <<= 8;
|
||||||
ret += machine.main_memory[address + i as usize] as u64;
|
ret += self.main_memory[address + i as usize] as u64;
|
||||||
}
|
}
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
@ -169,13 +169,13 @@ impl Machine {
|
|||||||
/// - **size** the number of bytes to write (1, 2, 4 or 8)
|
/// - **size** the number of bytes to write (1, 2, 4 or 8)
|
||||||
/// - **address** the address to write to
|
/// - **address** the address to write to
|
||||||
/// - **value** data to be written
|
/// - **value** data to be written
|
||||||
pub fn write_memory(machine: &mut Machine, size: i32, address: usize, value: u64) {
|
pub fn write_memory(&mut self, size: i32, address: usize, value: u64) {
|
||||||
if ![1, 2, 4, 8].contains(&size) {
|
if ![1, 2, 4, 8].contains(&size) {
|
||||||
panic!("ERROR write_memory: WRONG `size` PARAMETER ({size}), must be 1, 2, 4 or 8")
|
panic!("ERROR write_memory: WRONG `size` PARAMETER ({size}), must be 1, 2, 4 or 8")
|
||||||
}
|
}
|
||||||
for i in 0..size as usize {
|
for i in 0..size as usize {
|
||||||
let inv_i = size as usize - i - 1;
|
let inv_i = size as usize - i - 1;
|
||||||
machine.main_memory[address + i] = ((value & 0xff << (8 * inv_i)) >> (inv_i * 8)) as u8;
|
self.main_memory[address + i] = ((value & 0xff << (8 * inv_i)) >> (inv_i * 8)) as u8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,11 +185,11 @@ impl Machine {
|
|||||||
/// ### Parameters
|
/// ### Parameters
|
||||||
///
|
///
|
||||||
/// - **machine** contains the memory
|
/// - **machine** contains the memory
|
||||||
pub fn _extract_memory(machine: &mut Machine){
|
pub fn _extract_memory(&mut self){
|
||||||
let file_path = "burritos_memory.txt";
|
let file_path = "burritos_memory.txt";
|
||||||
let write_to_file = |path| -> std::io::Result<File> {
|
let write_to_file = |path| -> std::io::Result<File> {
|
||||||
let mut file = File::create(path)?;
|
let mut file = File::create(path)?;
|
||||||
file.write_all(&machine.main_memory)?;
|
file.write_all(&self.main_memory)?;
|
||||||
Ok(file)
|
Ok(file)
|
||||||
};
|
};
|
||||||
match write_to_file(file_path) {
|
match write_to_file(file_path) {
|
||||||
@ -198,20 +198,20 @@ impl Machine {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_machine_status(machine: &mut Machine) {
|
pub fn print_machine_status(&mut self) {
|
||||||
println!("######### Machine status #########");
|
println!("######### Machine status #########");
|
||||||
for i in (0..32).step_by(3) {
|
for i in (0..32).step_by(3) {
|
||||||
print!(">{0: <4} : {1:<16x} ", print::REG_X[i], machine.int_reg.get_reg(i));
|
print!(">{0: <4} : {1:<16x} ", print::REG_X[i], self.int_reg.get_reg(i));
|
||||||
print!(">{0: <4} : {1:<16x} ", print::REG_X[i+1], machine.int_reg.get_reg(i+1));
|
print!(">{0: <4} : {1:<16x} ", print::REG_X[i+1], self.int_reg.get_reg(i+1));
|
||||||
if i+2 < 32 {
|
if i+2 < 32 {
|
||||||
print!(">{0: <4} : {1:<16x} ", print::REG_X[i+2], machine.int_reg.get_reg(i+2));
|
print!(">{0: <4} : {1:<16x} ", print::REG_X[i+2], self.int_reg.get_reg(i+2));
|
||||||
}
|
}
|
||||||
println!();
|
println!();
|
||||||
}
|
}
|
||||||
println!("________________SP________________");
|
println!("________________SP________________");
|
||||||
let sp_index = machine.int_reg.get_reg(2);
|
let sp_index = self.int_reg.get_reg(2);
|
||||||
for i in 0..5 {
|
for i in 0..5 {
|
||||||
println!("SP+{:<2} : {:16x}", i*8, Self::read_memory(machine, 8, (sp_index + i*8) as usize));
|
println!("SP+{:<2} : {:16x}", i*8, Self::read_memory(self, 8, (sp_index + i*8) as usize));
|
||||||
}
|
}
|
||||||
println!("##################################");
|
println!("##################################");
|
||||||
}
|
}
|
||||||
@ -229,9 +229,9 @@ impl Machine {
|
|||||||
/// ### Parameters
|
/// ### Parameters
|
||||||
///
|
///
|
||||||
/// - **machine** which contains a table of instructions
|
/// - **machine** which contains a table of instructions
|
||||||
pub fn run(machine : &mut Machine){
|
pub fn run(&mut self){
|
||||||
while Machine::one_instruction(machine) == 0 {}
|
while Machine::one_instruction(self) == 0 {}
|
||||||
println!("trace : \n{}", machine.registers_trace);
|
println!("trace : \n{}", self.registers_trace);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// execute the current instruction
|
/// execute the current instruction
|
||||||
|
@ -216,7 +216,7 @@ pub fn print(ins: Instruction, pc: i32) -> String { //TODO pc should be u64
|
|||||||
RISCV_SYSTEM => {
|
RISCV_SYSTEM => {
|
||||||
"ecall".to_string()
|
"ecall".to_string()
|
||||||
},
|
},
|
||||||
_ => todo!("{:x} opcode non géré pc : {:x}, value : {:x}", ins.opcode, pc, ins.value) // Change todo! to panic! in the future, I put todo! because there's a lot of opcode currently not implemented
|
_ => unreachable!("{:x} opcode non géré pc : {:x}, value : {:x}", ins.opcode, pc, ins.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user