1
0
mirror of https://github.com/sgmarz/osblog.git synced 2024-11-24 02:16:19 +04:00

Add Process structure and routines.

This commit is contained in:
Stephen Marz 2019-11-27 17:02:07 -05:00
parent 4ec1301e8f
commit d0c3c9ff6e
2 changed files with 95 additions and 26 deletions

View File

@ -9,10 +9,10 @@
alloc_prelude, alloc_prelude,
const_raw_ptr_to_usize_cast)] const_raw_ptr_to_usize_cast)]
#[macro_use] // #[macro_use]
extern crate alloc; extern crate alloc;
// This is experimental and requires alloc_prelude as a feature // This is experimental and requires alloc_prelude as a feature
use alloc::prelude::v1::*; // use alloc::prelude::v1::*;
// /////////////////////////////////// // ///////////////////////////////////
// / RUST MACROS // / RUST MACROS
@ -327,38 +327,24 @@ extern "C" fn kmain() {
// kmain() starts in supervisor mode. So, we should have the trap // kmain() starts in supervisor mode. So, we should have the trap
// vector setup and the MMU turned on when we get here. // vector setup and the MMU turned on when we get here.
// Create a new scope so that we can test the global allocator and // Initialize the process list and anything else that needs to be done,
// deallocator // here.
{ process::init();
// We have the global allocator, so let's see if that works!
let k = Box::<u32>::new(100);
println!("Boxed value = {}", *k);
// The following comes from the Rust documentation:
// some bytes, in a vector
let sparkle_heart = vec![240, 159, 146, 150];
// We know these bytes are valid, so we'll use `unwrap()`.
// This will MOVE the vector.
let sparkle_heart = String::from_utf8(sparkle_heart).unwrap();
println!("String = {}", sparkle_heart);
println!("\n\nAllocations of a box, vector, and string");
kmem::print_table();
}
println!("\n\nEverything should now be free:");
kmem::print_table(); kmem::print_table();
unsafe { // unsafe {
// Set the next machine timer to fire. // Set the next machine timer to fire.
let mtimecmp = 0x0200_4000 as *mut u64; // let mtimecmp = 0x0200_4000 as *mut u64;
let mtime = 0x0200_bff8 as *const u64; // let mtime = 0x0200_bff8 as *const u64;
// The frequency given by QEMU is 10_000_000 Hz, so this sets // The frequency given by QEMU is 10_000_000 Hz, so this sets
// the next interrupt to fire one second from now. // the next interrupt to fire one second from now.
mtimecmp.write_volatile(mtime.read_volatile() + 10_000_000); // mtimecmp.write_volatile(mtime.read_volatile() + 10_000_000);
// Let's cause a page fault and see what happens. This should trap // Let's cause a page fault and see what happens. This should trap
// to m_trap under trap.rs // to m_trap under trap.rs
let v = 0x0 as *mut u64; // let v = 0x0 as *mut u64;
v.write_volatile(0); // v.write_volatile(0);
} // }
// If we get here, the Box, vec, and String should all be freed since // If we get here, the Box, vec, and String should all be freed since
// they go out of scope. This calls their "Drop" trait. // they go out of scope. This calls their "Drop" trait.

View File

@ -4,6 +4,45 @@
// 27 Nov 2019 // 27 Nov 2019
use crate::cpu::TrapFrame; use crate::cpu::TrapFrame;
use crate::page::{alloc, dealloc};
use alloc::collections::linked_list::LinkedList;
// Here, we store a process list. It uses the global allocator
// that we made before and its job is to store all processes.
// We will have this list OWN the process. So, anytime we want
// the process, we will consult the process list.
static mut PROCESS_LIST: LinkedList<Process> = LinkedList::new();
static mut CURRENT_0: u16 = 0;
/// We will eventually move this function out of here, but its
/// job is just to take a slot in the process list.
fn init_process() {
loop {
unsafe {
asm!("wfi");
}
}
}
/// Add a process given a function address and then
/// push it onto the LinkedList. Uses Process::new_default
/// to create a new stack, etc.
pub fn add_process_default(proc: fn()) {
unsafe {
let p = Process::new_default(proc);
PROCESS_LIST.push_back(p);
}
}
pub fn init() {
add_process_default(init_process);
unsafe {
let p = PROCESS_LIST.back();
if let Some(pd) = p {
CURRENT_0 = pd.pid;
}
}
}
// Let's represent this in C ABI. We do this // Let's represent this in C ABI. We do this
// because we need to access some of the fields // because we need to access some of the fields
@ -14,7 +53,51 @@ use crate::cpu::TrapFrame;
pub struct Process { pub struct Process {
frame: TrapFrame, frame: TrapFrame,
stack: *mut u8, stack: *mut u8,
program_counter: usize,
pid: u16,
data: ProcessData,
} }
impl Process {
pub fn new_default(func: fn()) -> Self {
let pd;
unsafe {
let plb = PROCESS_LIST.back();
if let Some(p) = plb {
pd = p.pid + 1;
}
else {
pd = 1
}
}
Process {
frame: TrapFrame::zero(),
stack: alloc(1),
program_counter: func as usize,
pid: pd,
data: ProcessData::zero()
}
}
}
impl Drop for Process {
fn drop(&mut self) {
dealloc(self.stack);
}
}
// The private data in a process contains information
// that is relevant to where we are, including the path
// and open file descriptors.
pub struct ProcessData {
cwd_path: [u8; 128],
}
impl ProcessData {
pub fn zero() -> Self {
ProcessData {
cwd_path: [0; 128],
}
}
}