Skip to content

Commit 7a51509

Browse files
committed
v0.8.3: basic fork impl
1 parent 1f7cbad commit 7a51509

13 files changed

Lines changed: 170 additions & 102 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/app/fork/src/main.rs

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,43 @@
33

44
extern crate alloc;
55
extern crate lib;
6-
76
use lib::*;
87

8+
static mut M: u64 = 0xdeadbeef;
9+
910
fn main() {
10-
let mut c = 23;
11+
let mut c = 32;
12+
13+
// do not alloc heap before `fork`
14+
// which may cause unexpected behavior since we won't copy the heap in `fork`
1115
let ret = sys_fork();
1216

1317
if ret == 0 {
14-
// println!("I am the child process");
15-
// println!("Exiting...");
18+
println!("I am the child process");
19+
unsafe {
20+
println!("child read value of M: {:#x}", &M);
21+
}
22+
unsafe {
23+
M = 0x2333;
24+
println!("child changed the value of M: {:#x}", &M);
25+
}
1626
c += 32;
1727
} else {
18-
// println!("I am the parent process");
19-
// println!("Waiting for child to exit...");
20-
// let ret = sys_wait_pid(ret);
21-
// println!("Child exited with status {}", ret);
22-
c += 24;
23-
}
24-
unsafe {
25-
core::arch::asm!("hlt");
28+
println!("I am the parent process");
29+
30+
sys_stat();
31+
32+
println!("Waiting for child to exit...");
33+
34+
let ret = sys_wait_pid(ret);
35+
36+
println!("Child exited with status {}", ret);
37+
38+
unsafe {
39+
println!("parent read value of M: {:#x}", &M);
40+
}
41+
42+
c += 1024;
2643
}
2744
sys_exit(c);
2845
}

pkg/app/sh/src/main.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ use alloc::string::String;
1313
extern crate lib;
1414

1515
fn main() {
16-
sys_spawn("/APP/FORK");
16+
services::exec("FORK", "/APP/");
17+
1718
let mut root_dir = String::from("/APP/");
1819
println!("<<< Welcome to GGOS shell >>>");
1920
loop {

pkg/app/sh/src/services.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,6 @@ pub fn exec(path: &str, root_dir: &str) {
116116
if pid == 0 {
117117
errln!("failed to spawn process: {}", path);
118118
return;
119-
} else {
120-
println!("[+] spawned process: {}#{}", path, pid);
121119
}
122120

123121
let ret = sys_wait_pid(pid);

pkg/elf/src/lib.rs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ pub fn map_stack(
6565
page_table: &mut impl Mapper<Size4KiB>,
6666
frame_allocator: &mut impl FrameAllocator<Size4KiB>,
6767
) -> Result<(), MapToError<Size4KiB>> {
68-
trace!("mapping stack at {:#x}", addr);
68+
trace!("Mapping stack at {:#x}", addr);
6969
// create a stack
7070
let stack_start = Page::containing_address(VirtAddr::new(addr));
7171
let stack_end = stack_start + pages;
@@ -83,6 +83,8 @@ pub fn map_stack(
8383
}
8484
}
8585

86+
trace!("Stack hint: {:#x} -> {:#x}", addr, page_table.translate_page(stack_start).unwrap().start_address());
87+
8688
Ok(())
8789
}
8890

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

99101
let stack_start = Page::containing_address(VirtAddr::new(addr));
102+
103+
trace!("Stack hint: {:#x} -> {:#x}", addr, page_table.translate_page(stack_start).unwrap().start_address());
104+
100105
let stack_end = stack_start + pages;
101106

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

136141
let flags = segment.flags();
137142
let mut page_table_flags = PageTableFlags::PRESENT;
143+
138144
if !flags.is_execute() {
139-
page_table_flags |= PageTableFlags::NO_EXECUTE
140-
};
145+
page_table_flags |= PageTableFlags::NO_EXECUTE;
146+
}
147+
141148
if flags.is_write() {
142-
page_table_flags |= PageTableFlags::WRITABLE
143-
};
149+
page_table_flags |= PageTableFlags::WRITABLE;
150+
}
144151

152+
trace!("Segment page table flag: {:?}", page_table_flags);
145153
for frame in PhysFrame::range_inclusive(start_frame, end_frame) {
146154
let offset = frame - start_frame;
147155
let page = start_page + offset;

pkg/kernel/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "ggos_kernel"
3-
version = "0.8.0"
3+
version = "0.8.3"
44
edition = "2021"
55
authors = ["GZTime <Time.GZ@outlook.com>"]
66
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

pkg/kernel/src/interrupt/handlers.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use super::*;
22
use crate::utils::Registers;
33
use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame, PageFaultErrorCode};
4+
use x86_64::registers::control::Cr2;
45

56
pub unsafe fn reg_idt(idt: &mut InterruptDescriptorTable) {
67
idt.divide_error.set_handler_fn(divide_error_handler);
@@ -24,8 +25,10 @@ pub unsafe fn reg_idt(idt: &mut InterruptDescriptorTable) {
2425
.set_handler_fn(stack_segment_fault_handler);
2526
idt.general_protection_fault
2627
.set_handler_fn(general_protection_fault_handler);
28+
2729
idt.page_fault.set_handler_fn(page_fault_handler)
28-
.set_stack_index(crate::gdt::SYSCALL_IST_INDEX);
30+
.set_stack_index(crate::gdt::PAGE_FAULT_IST_INDEX);
31+
2932
idt.alignment_check.set_handler_fn(alignment_check_handler);
3033
idt.machine_check.set_handler_fn(machine_check_handler);
3134
idt.simd_floating_point
@@ -157,13 +160,11 @@ pub extern "C" fn syscall(mut regs: Registers, mut sf: InterruptStackFrame) {
157160
as_handler!(syscall);
158161

159162
pub extern "x86-interrupt" fn page_fault_handler(
160-
mut stack_frame: InterruptStackFrame,
163+
stack_frame: InterruptStackFrame,
161164
err_code: PageFaultErrorCode,
162165
) {
163-
if let Err(_) = crate::process::try_resolve_page_fault(err_code, &mut stack_frame) {
164-
panic!(
165-
"EXCEPTION: PAGE FAULT, ERROR_CODE: {:?}\n\n{:#?}",
166-
err_code, stack_frame
167-
);
168-
}
166+
panic!(
167+
"EXCEPTION: PAGE FAULT, ERROR_CODE: {:?}\n\nTrying to access: {:#x}\n{:#?}",
168+
err_code, Cr2::read(), stack_frame
169+
);
169170
}

pkg/kernel/src/memory/gdt.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use x86_64::VirtAddr;
55

66
pub const DOUBLE_FAULT_IST_INDEX: u16 = 0;
77
pub const SYSCALL_IST_INDEX: u16 = 1;
8+
pub const PAGE_FAULT_IST_INDEX: u16 = 2;
89
pub const CONTEXT_SWITCH_IST_INDEX: u16 = 0;
910

1011
lazy_static! {
@@ -23,7 +24,15 @@ lazy_static! {
2324
static mut STACK: [u8; STACK_SIZE] = [0; STACK_SIZE];
2425
let stack_start = VirtAddr::from_ptr(unsafe { &STACK });
2526
let stack_end = stack_start + STACK_SIZE;
26-
info!("Syscall IST: 0x{:016x}-0x{:016x}", stack_start.as_u64(), stack_end.as_u64());
27+
info!("Syscall IST : 0x{:016x}-0x{:016x}", stack_start.as_u64(), stack_end.as_u64());
28+
stack_end
29+
};
30+
tss.interrupt_stack_table[PAGE_FAULT_IST_INDEX as usize] = {
31+
const STACK_SIZE: usize = 0x2000;
32+
static mut STACK: [u8; STACK_SIZE] = [0; STACK_SIZE];
33+
let stack_start = VirtAddr::from_ptr(unsafe { &STACK });
34+
let stack_end = stack_start + STACK_SIZE;
35+
info!("Page Fault IST : 0x{:016x}-0x{:016x}", stack_start.as_u64(), stack_end.as_u64());
2736
stack_end
2837
};
2938
tss

pkg/kernel/src/process/manager.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ impl ProcessManager {
157157
p.pause();
158158
p.init_stack_frame(
159159
VirtAddr::new_truncate(elf.header.pt2.entry_point()),
160-
VirtAddr::new_truncate(STACK_TOP),
160+
VirtAddr::new_truncate(STACK_BOT + STACK_SIZE),
161161
);
162162
p.init_elf(elf);
163163
// info!("Spawn process: {}#{}", p.name(), p.pid());

pkg/kernel/src/process/mod.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,9 @@ use x86_64::structures::idt::PageFaultErrorCode;
2222
use self::manager::init_PROCESS_MANAGER;
2323

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

2829
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
2930
pub enum ProgramStatus {
@@ -34,7 +35,7 @@ pub enum ProgramStatus {
3435
Dead,
3536
}
3637

37-
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
38+
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
3839
pub struct ProcessId(pub u16);
3940

4041
impl ProcessId {
@@ -50,6 +51,12 @@ impl core::fmt::Display for ProcessId {
5051
}
5152
}
5253

54+
impl core::fmt::Debug for ProcessId {
55+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
56+
write!(f, "{}", self.0)
57+
}
58+
}
59+
5360
impl From<ProcessId> for u16 {
5461
fn from(pid: ProcessId) -> Self {
5562
pid.0
@@ -130,13 +137,13 @@ pub fn current_pid() -> ProcessId {
130137
})
131138
}
132139

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

137144
x86_64::instructions::interrupts::without_interrupts(|| {
138145
let manager = get_process_manager_for_sure();
139-
debug!("Current process: {:?}", manager.current());
146+
debug!("Current process: {:#?}", manager.current());
140147
});
141148

142149
Err(())

0 commit comments

Comments
 (0)