Skip to content

Commit

Permalink
v0.8.3: basic fork impl
Browse files Browse the repository at this point in the history
  • Loading branch information
GZTimeWalker committed May 17, 2022
1 parent 1f7cbad commit 7a51509
Show file tree
Hide file tree
Showing 13 changed files with 170 additions and 102 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

41 changes: 29 additions & 12 deletions pkg/app/fork/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,43 @@

extern crate alloc;
extern crate lib;

use lib::*;

static mut M: u64 = 0xdeadbeef;

fn main() {
let mut c = 23;
let mut c = 32;

// do not alloc heap before `fork`
// which may cause unexpected behavior since we won't copy the heap in `fork`
let ret = sys_fork();

if ret == 0 {
// println!("I am the child process");
// println!("Exiting...");
println!("I am the child process");
unsafe {
println!("child read value of M: {:#x}", &M);
}
unsafe {
M = 0x2333;
println!("child changed the value of M: {:#x}", &M);
}
c += 32;
} else {
// println!("I am the parent process");
// println!("Waiting for child to exit...");
// let ret = sys_wait_pid(ret);
// println!("Child exited with status {}", ret);
c += 24;
}
unsafe {
core::arch::asm!("hlt");
println!("I am the parent process");

sys_stat();

println!("Waiting for child to exit...");

let ret = sys_wait_pid(ret);

println!("Child exited with status {}", ret);

unsafe {
println!("parent read value of M: {:#x}", &M);
}

c += 1024;
}
sys_exit(c);
}
Expand Down
3 changes: 2 additions & 1 deletion pkg/app/sh/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ use alloc::string::String;
extern crate lib;

fn main() {
sys_spawn("/APP/FORK");
services::exec("FORK", "/APP/");

let mut root_dir = String::from("/APP/");
println!("<<< Welcome to GGOS shell >>>");
loop {
Expand Down
2 changes: 0 additions & 2 deletions pkg/app/sh/src/services.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,6 @@ pub fn exec(path: &str, root_dir: &str) {
if pid == 0 {
errln!("failed to spawn process: {}", path);
return;
} else {
println!("[+] spawned process: {}#{}", path, pid);
}

let ret = sys_wait_pid(pid);
Expand Down
20 changes: 14 additions & 6 deletions pkg/elf/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ pub fn map_stack(
page_table: &mut impl Mapper<Size4KiB>,
frame_allocator: &mut impl FrameAllocator<Size4KiB>,
) -> Result<(), MapToError<Size4KiB>> {
trace!("mapping stack at {:#x}", addr);
trace!("Mapping stack at {:#x}", addr);
// create a stack
let stack_start = Page::containing_address(VirtAddr::new(addr));
let stack_end = stack_start + pages;
Expand All @@ -83,6 +83,8 @@ pub fn map_stack(
}
}

trace!("Stack hint: {:#x} -> {:#x}", addr, page_table.translate_page(stack_start).unwrap().start_address());

Ok(())
}

Expand All @@ -94,9 +96,12 @@ pub fn unmap_stack(
frame_deallocator: &mut impl FrameDeallocator<Size4KiB>,
do_dealloc: bool,
) -> Result<(), UnmapError> {
trace!("unmapping stack at {:#x}", addr);
trace!("Unmapping stack at {:#x}", addr);

let stack_start = Page::containing_address(VirtAddr::new(addr));

trace!("Stack hint: {:#x} -> {:#x}", addr, page_table.translate_page(stack_start).unwrap().start_address());

let stack_end = stack_start + pages;

for page in Page::range(stack_start, stack_end) {
Expand Down Expand Up @@ -135,13 +140,16 @@ fn map_segment(

let flags = segment.flags();
let mut page_table_flags = PageTableFlags::PRESENT;

if !flags.is_execute() {
page_table_flags |= PageTableFlags::NO_EXECUTE
};
page_table_flags |= PageTableFlags::NO_EXECUTE;
}

if flags.is_write() {
page_table_flags |= PageTableFlags::WRITABLE
};
page_table_flags |= PageTableFlags::WRITABLE;
}

trace!("Segment page table flag: {:?}", page_table_flags);
for frame in PhysFrame::range_inclusive(start_frame, end_frame) {
let offset = frame - start_frame;
let page = start_page + offset;
Expand Down
2 changes: 1 addition & 1 deletion pkg/kernel/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ggos_kernel"
version = "0.8.0"
version = "0.8.3"
edition = "2021"
authors = ["GZTime <[email protected]>"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand Down
17 changes: 9 additions & 8 deletions pkg/kernel/src/interrupt/handlers.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use super::*;
use crate::utils::Registers;
use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame, PageFaultErrorCode};
use x86_64::registers::control::Cr2;

pub unsafe fn reg_idt(idt: &mut InterruptDescriptorTable) {
idt.divide_error.set_handler_fn(divide_error_handler);
Expand All @@ -24,8 +25,10 @@ pub unsafe fn reg_idt(idt: &mut InterruptDescriptorTable) {
.set_handler_fn(stack_segment_fault_handler);
idt.general_protection_fault
.set_handler_fn(general_protection_fault_handler);

idt.page_fault.set_handler_fn(page_fault_handler)
.set_stack_index(crate::gdt::SYSCALL_IST_INDEX);
.set_stack_index(crate::gdt::PAGE_FAULT_IST_INDEX);

idt.alignment_check.set_handler_fn(alignment_check_handler);
idt.machine_check.set_handler_fn(machine_check_handler);
idt.simd_floating_point
Expand Down Expand Up @@ -157,13 +160,11 @@ pub extern "C" fn syscall(mut regs: Registers, mut sf: InterruptStackFrame) {
as_handler!(syscall);

pub extern "x86-interrupt" fn page_fault_handler(
mut stack_frame: InterruptStackFrame,
stack_frame: InterruptStackFrame,
err_code: PageFaultErrorCode,
) {
if let Err(_) = crate::process::try_resolve_page_fault(err_code, &mut stack_frame) {
panic!(
"EXCEPTION: PAGE FAULT, ERROR_CODE: {:?}\n\n{:#?}",
err_code, stack_frame
);
}
panic!(
"EXCEPTION: PAGE FAULT, ERROR_CODE: {:?}\n\nTrying to access: {:#x}\n{:#?}",
err_code, Cr2::read(), stack_frame
);
}
11 changes: 10 additions & 1 deletion pkg/kernel/src/memory/gdt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use x86_64::VirtAddr;

pub const DOUBLE_FAULT_IST_INDEX: u16 = 0;
pub const SYSCALL_IST_INDEX: u16 = 1;
pub const PAGE_FAULT_IST_INDEX: u16 = 2;
pub const CONTEXT_SWITCH_IST_INDEX: u16 = 0;

lazy_static! {
Expand All @@ -23,7 +24,15 @@ lazy_static! {
static mut STACK: [u8; STACK_SIZE] = [0; STACK_SIZE];
let stack_start = VirtAddr::from_ptr(unsafe { &STACK });
let stack_end = stack_start + STACK_SIZE;
info!("Syscall IST: 0x{:016x}-0x{:016x}", stack_start.as_u64(), stack_end.as_u64());
info!("Syscall IST : 0x{:016x}-0x{:016x}", stack_start.as_u64(), stack_end.as_u64());
stack_end
};
tss.interrupt_stack_table[PAGE_FAULT_IST_INDEX as usize] = {
const STACK_SIZE: usize = 0x2000;
static mut STACK: [u8; STACK_SIZE] = [0; STACK_SIZE];
let stack_start = VirtAddr::from_ptr(unsafe { &STACK });
let stack_end = stack_start + STACK_SIZE;
info!("Page Fault IST : 0x{:016x}-0x{:016x}", stack_start.as_u64(), stack_end.as_u64());
stack_end
};
tss
Expand Down
2 changes: 1 addition & 1 deletion pkg/kernel/src/process/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ impl ProcessManager {
p.pause();
p.init_stack_frame(
VirtAddr::new_truncate(elf.header.pt2.entry_point()),
VirtAddr::new_truncate(STACK_TOP),
VirtAddr::new_truncate(STACK_BOT + STACK_SIZE),
);
p.init_elf(elf);
// info!("Spawn process: {}#{}", p.name(), p.pid());
Expand Down
17 changes: 12 additions & 5 deletions pkg/kernel/src/process/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ use x86_64::structures::idt::PageFaultErrorCode;
use self::manager::init_PROCESS_MANAGER;

const STACK_BOT: u64 = 0x0000_2000_0000_0000;
const STACK_PAGES: u64 = 512;
const STACK_TOP: u64 = STACK_BOT + STACK_PAGES * 0x1000;
const STACK_PAGES: u64 = 0x200;
const STACK_SIZE: u64 = STACK_PAGES * crate::memory::PAGE_SIZE;
const STACK_START_MASK: u64 = !(STACK_SIZE - 1);

#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum ProgramStatus {
Expand All @@ -34,7 +35,7 @@ pub enum ProgramStatus {
Dead,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct ProcessId(pub u16);

impl ProcessId {
Expand All @@ -50,6 +51,12 @@ impl core::fmt::Display for ProcessId {
}
}

impl core::fmt::Debug for ProcessId {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{}", self.0)
}
}

impl From<ProcessId> for u16 {
fn from(pid: ProcessId) -> Self {
pid.0
Expand Down Expand Up @@ -130,13 +137,13 @@ pub fn current_pid() -> ProcessId {
})
}

pub fn try_resolve_page_fault(err_code: PageFaultErrorCode, sf: &mut InterruptStackFrame) -> Result<(),()> {
pub fn try_resolve_page_fault(_err_code: PageFaultErrorCode, _sf: &mut InterruptStackFrame) -> Result<(),()> {
let addr = Cr2::read();
debug!("Trying to access address: {:?}", addr);

x86_64::instructions::interrupts::without_interrupts(|| {
let manager = get_process_manager_for_sure();
debug!("Current process: {:?}", manager.current());
debug!("Current process: {:#?}", manager.current());
});

Err(())
Expand Down
Loading

0 comments on commit 7a51509

Please sign in to comment.