2020-04-22 04:30:09 +04:00
|
|
|
// test.rs
|
|
|
|
|
2020-05-15 20:01:03 +04:00
|
|
|
use crate::{elf,
|
2020-05-15 19:46:51 +04:00
|
|
|
buffer::Buffer,
|
|
|
|
fs::MinixFileSystem,
|
2020-05-15 20:01:03 +04:00
|
|
|
process::{PROCESS_LIST,
|
|
|
|
PROCESS_LIST_MUTEX}};
|
2020-05-15 18:34:37 +04:00
|
|
|
use alloc::string::String;
|
2020-04-24 22:39:56 +04:00
|
|
|
|
2020-04-26 16:33:49 +04:00
|
|
|
/// Test block will load raw binaries into memory to execute them. This function
|
|
|
|
/// will load ELF files and try to execute them.
|
|
|
|
pub fn test_elf() {
|
2020-05-15 18:34:37 +04:00
|
|
|
// This won't be necessary after we connect this to the VFS, but for now, we need it.
|
2020-05-15 18:37:40 +04:00
|
|
|
const BDEV: usize = 8;
|
2020-05-15 20:32:39 +04:00
|
|
|
// This could be better. We should see what our probe gave us, and it if is
|
|
|
|
// a block device, init the filesystem.
|
|
|
|
MinixFileSystem::init(8);
|
2020-05-15 18:40:37 +04:00
|
|
|
let file_to_read = String::from("/helloworld.elf");
|
2020-05-15 20:29:59 +04:00
|
|
|
let desc = MinixFileSystem::open(BDEV, &file_to_read).ok();
|
2020-05-15 18:34:37 +04:00
|
|
|
if desc.is_none() {
|
2020-05-15 18:40:37 +04:00
|
|
|
println!("Error reading {}", file_to_read);
|
2020-05-15 18:34:37 +04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
let ino = desc.unwrap();
|
2020-04-26 16:33:49 +04:00
|
|
|
// The bytes to read would usually come from the inode, but we are in an
|
2020-04-26 16:51:25 +04:00
|
|
|
// interrupt context right now, so we cannot pause. Usually, this would
|
|
|
|
// be done by an exec system call.
|
2020-05-15 19:46:51 +04:00
|
|
|
let mut buffer = Buffer::new(ino.size);
|
2020-04-26 16:33:49 +04:00
|
|
|
// Read the file from the disk. I got the inode by mounting
|
|
|
|
// the harddrive as a loop on Linux and stat'ing the inode.
|
2020-05-15 18:34:37 +04:00
|
|
|
|
2020-05-15 18:37:40 +04:00
|
|
|
let bytes_read = MinixFileSystem::read(BDEV, &ino, buffer.get_mut(), ino.size, 0);
|
2020-04-26 16:33:49 +04:00
|
|
|
// After compiling our program, I manually looked and saw it was 18,360
|
|
|
|
// bytes. So, to make sure we got the right one, I do a manual check
|
|
|
|
// here.
|
2020-05-15 18:34:37 +04:00
|
|
|
if bytes_read != ino.size {
|
2020-04-26 16:33:49 +04:00
|
|
|
println!(
|
2020-05-15 18:34:37 +04:00
|
|
|
"Unable to load program, which should \
|
2020-04-26 16:51:25 +04:00
|
|
|
be {} bytes, got {}",
|
2020-05-15 18:34:37 +04:00
|
|
|
ino.size, bytes_read
|
2020-04-26 16:33:49 +04:00
|
|
|
);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// Let's get this program running!
|
|
|
|
// Everything is "page" based since we're going to map pages to
|
|
|
|
// user space. So, we need to know how many program pages we
|
|
|
|
// need. Each page is 4096 bytes.
|
2020-05-15 20:01:03 +04:00
|
|
|
let my_proc = elf::File::load_proc(&buffer, bytes_read as usize);
|
2020-05-15 20:11:28 +04:00
|
|
|
if my_proc.is_err() {
|
2020-05-15 20:01:03 +04:00
|
|
|
println!("Unable to load process");
|
2020-04-26 16:33:49 +04:00
|
|
|
return;
|
|
|
|
}
|
2020-05-15 20:11:28 +04:00
|
|
|
let my_proc = my_proc.ok().unwrap();
|
2020-05-02 03:10:56 +04:00
|
|
|
// I took a different tact here than in process.rs. In there I created
|
|
|
|
// the process while holding onto the process list. It might
|
|
|
|
// matter since this is asynchronous--it is being ran as a kernel process.
|
|
|
|
unsafe {
|
2020-05-15 18:34:37 +04:00
|
|
|
PROCESS_LIST_MUTEX.sleep_lock();
|
2020-05-02 03:10:56 +04:00
|
|
|
}
|
|
|
|
if let Some(mut pl) = unsafe { PROCESS_LIST.take() } {
|
|
|
|
// As soon as we push this process on the list, it'll be
|
|
|
|
// schedule-able.
|
|
|
|
println!(
|
|
|
|
"Added user process to the scheduler...get ready \
|
|
|
|
for take-off!"
|
|
|
|
);
|
|
|
|
pl.push_back(my_proc);
|
|
|
|
unsafe {
|
|
|
|
PROCESS_LIST.replace(pl);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
println!("Unable to spawn process.");
|
|
|
|
// Since my_proc couldn't enter the process list, it
|
|
|
|
// will be dropped and all of the associated allocations
|
|
|
|
// will be deallocated through the process' Drop trait.
|
|
|
|
}
|
|
|
|
unsafe {
|
|
|
|
PROCESS_LIST_MUTEX.unlock();
|
2020-05-02 03:02:58 +04:00
|
|
|
}
|
2020-04-26 16:33:49 +04:00
|
|
|
println!();
|
|
|
|
}
|
|
|
|
|