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:
parent
4ec1301e8f
commit
d0c3c9ff6e
@ -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.
|
||||||
|
|
||||||
|
@ -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],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user