diff --git a/Makefile b/Makefile
index 861f360..dd1f30a 100644
@@ -43,7 +43,7 @@ image: $(img)
cargo bootimage --no-default-features --features $(output),$(nic) --release --bin moros
dd conv=notrunc if=$(bin) of=$(img)
-opts = -m 32 -cpu max -nic model=$(nic) -hda $(img) -soundhw pcspk
+opts = -m 64 -cpu max -nic model=$(nic) -hda $(img) -soundhw pcspk
ifeq ($(output),serial)
opts += -display none -serial stdio
endif
diff --git a/dsk/bin/hello b/dsk/bin/hello
index e4301e6..e76d474 100755
Binary files a/dsk/bin/hello and b/dsk/bin/hello differ
diff --git a/dsk/bin/sleep b/dsk/bin/sleep
index a1081a5..73ddf4c 100644
Binary files a/dsk/bin/sleep and b/dsk/bin/sleep differ
diff --git a/src/sys/allocator.rs b/src/sys/allocator.rs
index a3df1dd..6cb8690 100644
@@ -18,7 +18,7 @@ static ALLOCATOR: LockedHeap = LockedHeap::empty();
pub fn init_heap(mapper: &mut impl Mapper<Size4KiB>, frame_allocator: &mut impl FrameAllocator<Size4KiB>) -> Result<(), MapToError<Size4KiB>> {
// Use half of the memory for the heap, caped to 16 MB because the allocator is too slow
- let heap_size = cmp::min(sys::mem::memory_size() / 2, 16 << 20);
+ let heap_size = cmp::min(sys::mem::memory_size() / 2, 32 << 20);
let pages = {
let heap_start = VirtAddr::new(HEAP_START as u64);
diff --git a/src/sys/gdt.rs b/src/sys/gdt.rs
index 625f864..a3109ee 100644
@@ -5,7 +5,7 @@ use x86_64::instructions::tables::load_tss;
use x86_64::structures::gdt::{Descriptor, GlobalDescriptorTable, SegmentSelector};
use x86_64::structures::tss::TaskStateSegment;
-const STACK_SIZE: usize = 8192;
+const STACK_SIZE: usize = 32 << 10;
pub const DOUBLE_FAULT_IST_INDEX: u16 = 0;
pub const PAGE_FAULT_IST_INDEX: u16 = 1;
pub const GENERAL_PROTECTION_FAULT_IST_INDEX: u16 = 2;
diff --git a/src/sys/idt.rs b/src/sys/idt.rs
index 7ba0638..a5959f8 100644
@@ -172,8 +172,11 @@ wrap!(syscall_handler => wrapped_syscall_handler);
// return a result in the RAX register and it will be overwritten when the
// context of the caller is restored.
extern "sysv64" fn syscall_handler(_stack_frame: &mut InterruptStackFrame, regs: &mut Registers) {
- printk!("DEBUG syscall handler: begin\n");
- sys::process::set_registers(*regs);
+ printk!("DEBUG: syscall handler {}\n", regs.rax);
+ use x86_64::registers::segmentation::{Segment, CS, DS};
+ let cs = CS::get_reg();
+ let ds = DS::get_reg();
+ printk!("DEBUG: syscall handler cs={:?}, ds={:?}\n", cs, ds);
// The registers order follow the System V ABI convention
let n = regs.rax;
@@ -181,7 +184,13 @@ extern "sysv64" fn syscall_handler(_stack_frame: &mut InterruptStackFrame, regs:
let arg2 = regs.rsi;
let arg3 = regs.rdx;
- printk!("DEBUG syscall handler: n={:#x}, arg1={:#x}, arg2={:#x}, arg3={:#x}\n", n, arg1, arg2, arg3);
+ if n == sys::syscall::number::EXIT || n == sys::syscall::number::SPAWN {
+ //printk!("DEBUG: syscall handler regs before\n");
+ sys::process::set_registers(*regs);
+ //printk!("DEBUG: syscall handler regs after\n");
+ }
+
+ printk!("DEBUG: syscall handler -> n={}, arg1={}, arg2={}, arg3={}\n", n, arg1, arg2, arg3);
regs.rax = sys::syscall::dispatcher(n, arg1, arg2, arg3);
printk!("DEBUG syscall handler: end\n");
unsafe { sys::pic::PICS.lock().notify_end_of_interrupt(0x80) };
diff --git a/src/sys/process.rs b/src/sys/process.rs
index d081f88..b2dd177 100644
@@ -9,7 +9,7 @@ use lazy_static::lazy_static;
use object::{Object, ObjectSegment};
use spin::RwLock;
-const MAX_FILE_HANDLES: usize = 64;
+const MAX_FILE_HANDLES: usize = 32;
lazy_static! {
pub static ref PROCESS_TABLE: RwLock<Vec<Process>> = RwLock::new(Vec::new());
@@ -49,10 +49,14 @@ impl ProcessData {
}
pub fn id() -> usize {
- PID.load(Ordering::SeqCst)
+ //PID.load(Ordering::SeqCst)
+ let id = PID.load(Ordering::SeqCst);
+ printk!("DEBUG: get pid {}\n", id);
+ id
}
pub fn set_id(id: usize) {
+ printk!("DEBUG: set pid {}\n", id);
PID.store(id, Ordering::SeqCst)
}
@@ -132,7 +136,9 @@ pub fn file_handle(handle: usize) -> Option<Resource> {
}
pub fn code_addr() -> u64 {
+ printk!("DEBUG: code_addr\n");
let table = PROCESS_TABLE.read();
+ printk!("DEBUG: code_addr pid={}\n", id());
let proc = &table[id()];
proc.code_addr
}
@@ -144,6 +150,7 @@ pub fn set_code_addr(addr: u64) {
}
pub fn ptr_from_addr(addr: u64) -> *mut u8 {
+ printk!("DEBUG: ptr_from_addr\n");
(code_addr() + addr) as *mut u8
}
@@ -218,6 +225,7 @@ impl Process {
}
fn create(bin: &[u8]) -> Result<usize, ()> {
+ printk!("DEBUG: process create\n");
let mut mapper = unsafe { sys::mem::mapper(VirtAddr::new(sys::mem::PHYS_MEM_OFFSET)) };
let mut frame_allocator = unsafe { sys::mem::BootInfoFrameAllocator::init(sys::mem::MEMORY_MAP.unwrap()) };
@@ -242,6 +250,7 @@ impl Process {
let mut entry_point = 0;
let code_ptr = code_addr as *mut u8;
if &bin[1..4] == b"ELF" { // ELF binary
+ printk!("DEBUG: process create: ELF binary\n");
if let Ok(obj) = object::File::parse(bin) {
entry_point = obj.entry();
for segment in obj.segments() {
@@ -257,6 +266,7 @@ impl Process {
}
}
} else { // Raw binary
+ printk!("DEBUG: process create: Raw binary\n");
for (i, op) in bin.iter().enumerate() {
unsafe {
let ptr = code_ptr.add(i);
@@ -265,17 +275,28 @@ impl Process {
}
}
+ printk!("DEBUG: process create: read table\n");
let mut table = PROCESS_TABLE.write();
+ printk!("DEBUG: process create: parent pid={}\n", id());
let parent = &table[id()];
- let dir = parent.data.dir.clone();
- let user = parent.data.user.clone();
- let data = ProcessData::new(&dir, user.as_deref());
+ //let data = parent.data.clone();
+ let dir = &parent.data.dir;
+ //printk!("DEBUG: process create: created dir '{}'\n", dir);
+ let user = parent.data.user.as_deref();
+ //printk!("DEBUG: process create: created user '{:?}'\n", user);
+ //printk!("DEBUG: process create: create data\n");
+ //let data = ProcessData::new(&dir, user.as_deref());
+ let data = ProcessData::new(dir, user);
+ //printk!("DEBUG: process create: created data\n");
let id = table.len();
+ printk!("DEBUG: process create: child pid={}\n", id);
let registers = Registers::default();
let proc = Process { id, code_addr, code_size, entry_point, data, registers };
+ printk!("DEBUG: process create: {:?}\n", proc);
table.push(proc);
//printk!("DEBUG: create proc: release write lock\n");
+ printk!("DEBUG: process create: ok\n");
Ok(id)
}
diff --git a/src/sys/syscall/mod.rs b/src/sys/syscall/mod.rs
index f843656..68cb735 100644
@@ -1,6 +1,8 @@
pub mod number;
pub mod service;
+pub use number::*;
+
use crate::sys;
use crate::sys::fs::FileStat;
@@ -46,7 +48,9 @@ pub fn dispatcher(n: usize, arg1: usize, arg2: usize, arg3: usize) -> usize {
}
number::WRITE => {
let handle = arg1;
+ printk!("DEBUG: write arg={:#x}\n", arg2 as u64);
let ptr = sys::process::ptr_from_addr(arg2 as u64);
+ printk!("DEBUG: write ptr={:#x}\n", ptr as u64);
let len = arg3;
let mut buf = unsafe { core::slice::from_raw_parts_mut(ptr, len) };
service::write(handle, &mut buf) as usize