Skip to content

Commit

Permalink
v0.9.3: dynamic alloc stack
Browse files Browse the repository at this point in the history
  • Loading branch information
GZTimeWalker committed May 18, 2022
1 parent 695fe4b commit f0f0d59
Show file tree
Hide file tree
Showing 9 changed files with 176 additions and 80 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.

13 changes: 13 additions & 0 deletions pkg/app/hello/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,19 @@ fn main() -> usize {
println!("Hello, world!!!");
let time = lib::sys_time();
println!("Now at: {}", time);

println!("Huge stack testing...");

let mut stack = [0u64; 0x1000];

for i in 0..stack.len() {
stack[i] = i as u64;
}

for i in 0..stack.len() / 256 {
println!("{:#05x} == {:#05x}", i * 256, stack[i * 256]);
}

println!("Exiting...");

233
Expand Down
2 changes: 2 additions & 0 deletions pkg/elf/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,10 @@ pub fn map_stack(
// create a stack
let stack_start = Page::containing_address(VirtAddr::new(addr));
let stack_end = stack_start + pages;
trace!("Page Range: {:?}({})", Page::range(stack_start, stack_end), pages);

let flags = PageTableFlags::PRESENT | PageTableFlags::WRITABLE;
trace!("Flags: {:?}", flags);

for page in Page::range(stack_start, stack_end) {
let frame = frame_allocator
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.9.1"
version = "0.9.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
16 changes: 8 additions & 8 deletions pkg/kernel/src/interrupt/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,12 +163,12 @@ pub extern "x86-interrupt" fn page_fault_handler(
stack_frame: InterruptStackFrame,
err_code: PageFaultErrorCode,
) {
warn!(
"EXCEPTION: PAGE FAULT, ERROR_CODE: {:?}\n\nTrying to access: {:#x}\n{:#?}",
err_code, Cr2::read(), stack_frame
);

crate::process::force_show_info();

panic!("Cannot handle page fault!");
if let Err(()) = crate::process::handle_page_fault(Cr2::read(), err_code) {
warn!(
"EXCEPTION: PAGE FAULT, ERROR_CODE: {:?}\n\nTrying to access: {:#x}\n{:#?}",
err_code, Cr2::read(), stack_frame
);
crate::process::force_show_info();
panic!("Cannot handle page fault!");
}
}
38 changes: 32 additions & 6 deletions pkg/kernel/src/process/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@ impl ProcessManager {
}

fn current_mut(&mut self) -> &mut Process {
self.processes.iter_mut().find(|x| x.pid() == self.cur_pid).unwrap()
self.processes
.iter_mut()
.find(|x| x.pid() == self.cur_pid)
.unwrap()
}

fn pid_mut(&mut self, pid: ProcessId) -> &mut Process {
Expand Down Expand Up @@ -161,16 +164,14 @@ impl ProcessManager {
trace!(
"Init stack frame with: \n entry: {:#x}\n stack: {:#x}",
elf.header.pt2.entry_point(),
STACK_BOT + STACK_SIZE
STACK_INIT_TOP
);
p.init_stack_frame(
VirtAddr::new_truncate(elf.header.pt2.entry_point()),
VirtAddr::new_truncate(STACK_BOT + STACK_SIZE),
VirtAddr::new_truncate(STACK_INIT_TOP),
);
p.init_elf(&elf);
trace!("{:#?}", &p);
// info!("Spawn process: {}#{}", p.name(), p.pid());
// info!("Spawn process:\n\n{:?}\n", p);
let pid = p.pid();
self.processes.push(p);
pid
Expand Down Expand Up @@ -233,6 +234,26 @@ impl ProcessManager {
});
}

pub fn handle_page_fault(
&mut self,
addr: VirtAddr,
err_code: PageFaultErrorCode,
) -> Result<(), ()> {
if !err_code.contains(PageFaultErrorCode::PROTECTION_VIOLATION)
{
let cur_proc = self.current_mut();
trace!("Checking if {:#x} is on current process's stack", addr);
if cur_proc.is_on_stack(addr) {
cur_proc.try_alloc_new_stack_page(addr).unwrap();
Ok(())
} else {
Err(())
}
} else {
Err(())
}
}

pub fn kill(&mut self, pid: ProcessId, ret: isize) {
let p = self.processes.iter().find(|x| x.pid() == pid);

Expand All @@ -243,7 +264,12 @@ impl ProcessManager {

let p = p.unwrap();

debug!("Killing process {}#{} with ret code: {}", p.name(), pid, ret);
debug!(
"Killing process {}#{} with ret code: {}",
p.name(),
pid,
ret
);

let parent = p.parent();
let children = p.children();
Expand Down
28 changes: 23 additions & 5 deletions pkg/kernel/src/process/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,29 @@ use crate::{filesystem::get_volume, Registers, Resource};
use alloc::{string::String, vec, collections::BTreeMap};
use x86_64::{
registers::control::{Cr3, Cr2},
structures::idt::InterruptStackFrame,
structures::idt::InterruptStackFrame, VirtAddr,
};
use x86_64::structures::idt::PageFaultErrorCode;

use self::manager::init_PROCESS_MANAGER;
use self::sync::init_SEMAPHORES;

const STACK_BOT: u64 = 0x0000_2000_0000_0000;
const STACK_PAGES: u64 = 0x100;
const STACK_SIZE: u64 = STACK_PAGES * crate::memory::PAGE_SIZE;
const STACK_START_MASK: u64 = !(STACK_SIZE - 1);
// 0xffff_ff00_0000_0000 is the kernel's address space
const STACK_MAX_BOT: u64 = 0x0000_4000_0000_0000;
// stack max addr, every thread has a stack space
// from 0x????_????_0000_0000 to 0x????_????_ffff_ffff
// 0x100000000 bytes -> 4GiB
// allow 0x2000 (4096) threads run as a time
// 0x????_2000_????_???? -> 0x????_4000_????_????
// init alloc stack has size of 0x2000 (2 frames)
// every time we meet a page fault, we will alloc 2 frames, again
const STACK_MAX_PAGES: u64 = 0x100000;
const STACK_MAX_SIZE: u64 = STACK_MAX_PAGES * crate::memory::PAGE_SIZE;
const STACK_START_MASK: u64 = !(STACK_MAX_SIZE - 1);
// [bot..0x2000_0000_0000..top..0x4000_ffff_ffff]
// init stack: [0x4000_ffff_e000_..0x4000_ffff_ffff]
const STACT_INIT_BOT: u64 = STACK_MAX_BOT + STACK_MAX_SIZE - 0x2000;
const STACK_INIT_TOP: u64 = STACK_MAX_BOT + STACK_MAX_SIZE - 1;

#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum ProgramStatus {
Expand Down Expand Up @@ -271,3 +283,9 @@ pub fn force_show_info() {

debug!("{:#?}", get_process_manager_for_sure().current())
}

pub fn handle_page_fault(addr: VirtAddr, err_code: PageFaultErrorCode) -> Result<(), ()> {
x86_64::instructions::interrupts::without_interrupts(|| {
get_process_manager_for_sure().handle_page_fault(addr, err_code)
})
}
Loading

0 comments on commit f0f0d59

Please sign in to comment.