diff --git a/crates/init/build.sh b/crates/init/build.sh index 352645fc..2cc5376d 100755 --- a/crates/init/build.sh +++ b/crates/init/build.sh @@ -12,6 +12,9 @@ mkdir -p fs # cp shell.elf fs/ # ./ls.rs # cp ls.elf fs/ +./sharedMemTest.rs +cp sharedMemTest.elf fs/ + cargo run -q -p initfs --bin util \ -- create --compress --out fs.arc --root fs fs --verbose diff --git a/crates/init/fs/test2.txt b/crates/init/fs/test2.txt new file mode 100644 index 00000000..b205596a --- /dev/null +++ b/crates/init/fs/test2.txt @@ -0,0 +1 @@ +hello worldaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahello world \ No newline at end of file diff --git a/crates/init/sharedMemTest.rs b/crates/init/sharedMemTest.rs new file mode 100755 index 00000000..62d952a1 --- /dev/null +++ b/crates/init/sharedMemTest.rs @@ -0,0 +1,158 @@ +#!/usr/bin/env bash +#![doc = r##""##] +#![no_std] +#![no_main] + +#[macro_use] +extern crate ulib; + +use ulib::sys::{openat, close, mmap, munmap, wait, exit, MAP_PRIVATE, MAP_SHARED, MAP_FILE}; + +#[no_mangle] +fn main() { + + let root_fd = 3; + + let test_file_path = b"test.txt"; + let mut test_text_file = openat(root_fd, test_file_path, 0, 0).unwrap(); + + static HELLO_CHARS: [u8; 5] = *b"hello"; + static WORLD_CHARS: [u8; 5] = *b"world"; + + let mut mmap_addr: *mut u8 = + unsafe { mmap(0, 4096, 0, MAP_PRIVATE | MAP_FILE, test_text_file, 0).unwrap() } as *mut u8; + println!("Memory range is mmaped!"); + + for i in 0..5 { + let curr_char: u8 = unsafe { *(mmap_addr.wrapping_add(i)) }; + if curr_char != HELLO_CHARS[i] { + panic!( + "mmap filed file has an error at index {}! Expected {} got {}", + i, HELLO_CHARS[i] as char, curr_char as char + ); + } + } + + println!("mmap of test file succeeded!"); + unsafe { munmap(mmap_addr as *mut ()).unwrap() }; + _ = close(test_text_file); + + println!("starting mmap with offset test 1"); + let test_file_path2 = b"test2.txt"; + test_text_file = openat(root_fd, test_file_path2, 0, 0).unwrap(); + mmap_addr = + unsafe { mmap(0, 4096 * 2, 0, MAP_PRIVATE | MAP_FILE, test_text_file, 6).unwrap() } as *mut u8; + println!("mmap addr: {:x}", mmap_addr as usize); + + for i in 0..5 { + let curr_char: u8 = unsafe { *(mmap_addr.wrapping_add(i)) }; + if curr_char != WORLD_CHARS[i] { + panic!( + "mmap filed file has an error at index {}! Expected {} got {}", + i, WORLD_CHARS[i] as char, curr_char as char + ); + } + } + + println!("done with mmap with offset test 1"); + + println!("starting mmap with offset test 2"); + for i in 0..5 { + let curr_char: u8 = unsafe { *(mmap_addr.wrapping_add(i + 4096)) }; + if curr_char != WORLD_CHARS[i] { + panic!( + "mmap filed file has an error at index {}! Expected {} got {}", + i, WORLD_CHARS[i] as char, curr_char as char + ); + } + } + + println!("done with mmap with offset test 2"); + unsafe { munmap(mmap_addr as *mut ()).unwrap() }; + _ = close(test_text_file); + + println!("Starting shared memory test"); + + let shared_mem_fd = unsafe { ulib::sys::sys_memfd_create() as u32 }; + let shared_frame = + unsafe { ulib::sys::mmap(0, 4096, 0, MAP_SHARED, shared_mem_fd, 0) }.unwrap() as *mut u8; + let end_ptr: *mut u8 = shared_frame.wrapping_add(6); + unsafe { end_ptr.write_volatile('.' as u8) }; + assert_eq!(unsafe { end_ptr.read_volatile() }, '.' as u8); + + println!("Calling fork"); + let wait_fd = unsafe { ulib::sys::sys_fork() } as u32; + + if wait_fd == 0 { + for _i in 0..1000000 { + if unsafe { end_ptr.read_volatile() } == ('!' as u8) { + break; + } + } + + let end_val: u8 = unsafe { end_ptr.read_volatile() }; + if end_val != ('!' as u8) { + println!( + "Error: child expected to see '!' with val {} and instead found {}", + ('!' as u8), + end_val + ); + ulib::sys::exit(5); + } + + for i in 0..5 { + let curr_char = unsafe { *shared_frame.wrapping_add(i) } as char; + if curr_char != (HELLO_CHARS[i] as char) { + println!( + "Child found wrong char at index {}. Expected {} found {}", + i, + (HELLO_CHARS[i] as char), + curr_char + ); + ulib::sys::exit(5); + } + } + + println!("Child is done"); + ulib::sys::exit(0); + } else { + unsafe { + core::ptr::copy_nonoverlapping( + &raw const HELLO_CHARS[0], + shared_frame, + HELLO_CHARS.len(), + ); + shared_frame.wrapping_add(6).write('!' as u8); + } + + let child_exit_val = wait(wait_fd).unwrap(); + assert_eq!(child_exit_val, 0); + println!("done with shared memory test, parent received exit code 0 from child"); + } + + _ = unsafe { munmap(shared_frame as *mut ()) }; + + exit(15); +} diff --git a/crates/kernel/src/fs/initfs.rs b/crates/kernel/src/fs/initfs.rs index c27bbb5d..7441bfbd 100644 --- a/crates/kernel/src/fs/initfs.rs +++ b/crates/kernel/src/fs/initfs.rs @@ -3,6 +3,7 @@ use alloc::sync::{Arc, Weak}; use alloc::vec::Vec; use initfs::{Archive, ArchiveError}; +use crate::arch::memory::palloc::{Size4KiB, PAGE_ALLOCATOR}; use crate::process::fd::{ boxed_future, ArcFd, DirEntry, FileDescResult, FileDescriptor, FileKind, SmallFuture, }; @@ -252,8 +253,27 @@ impl FileDescriptor for InitFsFile { boxed_future(async move { Err(()) }) } } - fn mmap_page(&self, _offset: u64) -> SmallFuture> { - boxed_future(async move { None }) + fn mmap_page(&self, offset: u64) -> SmallFuture> { + if self.header.is_dir() { + return boxed_future(async move { None }); + } + + //File case, need to call read + boxed_future(async move { + let page = PAGE_ALLOCATOR.get().alloc_mapped_frame::(); + let page_paddr = page.paddr; + let page_virt = PAGE_ALLOCATOR.get().get_mapped_frame::(page); + let buf_ref = unsafe { core::slice::from_raw_parts_mut(page_virt as *mut u8, 4096) }; + match self.read(offset, buf_ref).await.as_result() { + Ok(_val) => { + return Some(FileDescResult::ok(page_paddr as u64)); + } + Err(_val) => { + println!("Read failed"); + return None; + } + } + }) } fn as_any(&self) -> &dyn core::any::Any { self diff --git a/crates/kernel/src/process/mem.rs b/crates/kernel/src/process/mem.rs index 313821c4..3cede081 100644 --- a/crates/kernel/src/process/mem.rs +++ b/crates/kernel/src/process/mem.rs @@ -13,6 +13,8 @@ use crate::event::context::Context; use crate::event::exceptions::DataAbortISS; use crate::syscall::proc::exit_user_thread; +use crate::syscall::fb_hack::MemFd; + use super::fd::ArcFd; #[derive(Debug)] @@ -38,7 +40,7 @@ pub struct MemoryRangeNode { #[derive(Clone)] pub enum MappingKind { Anon, - File(ArcFd), + File { fd: ArcFd, offset: usize }, } impl UserAddrSpace { @@ -94,6 +96,13 @@ impl UserAddrSpace { .await .unwrap(); + //Don't want to copy data in shared mem + if let MappingKind::File { fd, .. } = &node.kind { + if let Some(_s) = fd.as_any().downcast_ref::() { + continue; + } + } + let src_data = node.start as *const u8; let dst_data = node.start as *mut u8; let buf_ptr: *mut u8 = buffer.as_mut_ptr().cast(); @@ -194,18 +203,29 @@ impl UserAddrSpace { }; let leaf = unsafe { desc.leaf }; + if leaf.is_valid() { let new_desc = TranslationDescriptor::unset(); unsafe { set_translation_descriptor(self.table, virt_addr, 3, 0, new_desc, false) .unwrap() } + //Need this invalidation here or it still accesses old page + unsafe { + core::arch::asm! { + "dsb ISH", + "tlbi vaae1, {0}", + in(reg) (virt_addr >> 12) + //options(readonly, nostack, preserves_flags) + } + } + // TODO: free it match &vme.kind { MappingKind::Anon => { // TODO: free } - MappingKind::File(_arc) => { + MappingKind::File { .. } => { // TODO: notify file that it's unused? // (for ref counts, page cache?) } @@ -254,12 +274,23 @@ impl UserAddrSpace { desc } - MappingKind::File(fd) => { + MappingKind::File { + fd: arc_fd, + offset: file_offset, + } => { let offset = vaddr - vme.start; - let page = match fd.mmap_page(offset as u64).await.map(|r| r.as_result()) { + let page = match arc_fd + .mmap_page(offset as u64 + (*file_offset as u64)) + .await + .map(|r| r.as_result()) + { Some(Ok(page)) => page, - Some(Err(_e)) => return Err(MmapError::FileError), - None => return Err(MmapError::FileError), + Some(Err(_e)) => { + return Err(MmapError::FileError); + } + None => { + return Err(MmapError::FileError); + } }; let desc = LeafDescriptor::new(page as usize) .union(LeafDescriptor::UNPRIVILEGED_ACCESS) @@ -310,7 +341,6 @@ unsafe impl Sync for UserAddrSpace {} pub fn page_fault_handler(ctx: &mut Context, far: usize, _iss: DataAbortISS) -> *mut Context { run_async_handler(ctx, async move |mut context: HandlerContext<'_>| { let proc = context.cur_process().unwrap(); - // TODO: make sure misaligned loads don't loop here? let page_addr = (far / PAGE_SIZE) * PAGE_SIZE; diff --git a/crates/kernel/src/syscall/fb_hack.rs b/crates/kernel/src/syscall/fb_hack.rs index 24d4f173..1db58f70 100644 --- a/crates/kernel/src/syscall/fb_hack.rs +++ b/crates/kernel/src/syscall/fb_hack.rs @@ -99,7 +99,7 @@ pub unsafe fn sys_memfd_create(ctx: &mut Context) -> *mut Context { }) } -struct MemFd { +pub struct MemFd { pages: SpinLock>>, } diff --git a/crates/kernel/src/syscall/mmap.rs b/crates/kernel/src/syscall/mmap.rs index 88f9c9e3..0590c3c5 100644 --- a/crates/kernel/src/syscall/mmap.rs +++ b/crates/kernel/src/syscall/mmap.rs @@ -7,7 +7,8 @@ bitflags::bitflags! { } struct MmapFlags: u32 { const MAP_FIXED = 1 << 0; - const MAP_ANONYMOUS = 1 << 1; + const MAP_ANONYMOUS = 1 << 1; //if not set this indicates file + const MAP_SHARED = 1 << 2; //if not set indicates private mapping } } @@ -32,12 +33,13 @@ pub unsafe fn sys_mmap(ctx: &mut Context) -> *mut Context { }; let fd = ctx.regs[4]; - // TODO: File offset - let _offset = ctx.regs[5]; + let offset = ctx.regs[5]; run_async_handler(ctx, async move |mut context: HandlerContext<'_>| { let proc = context.cur_process().unwrap(); + let _is_shared: bool = flags.contains(MmapFlags::MAP_SHARED); + let kind = if flags.contains(MmapFlags::MAP_ANONYMOUS) { MappingKind::Anon } else { @@ -46,7 +48,7 @@ pub unsafe fn sys_mmap(ctx: &mut Context) -> *mut Context { context.regs().regs[0] = i64::from(-1) as usize; return context.resume_final(); }; - MappingKind::File(file) + MappingKind::File { fd: file, offset } }; let res; diff --git a/crates/kernel/src/syscall/mod.rs b/crates/kernel/src/syscall/mod.rs index 311e4ac8..64f6be3b 100644 --- a/crates/kernel/src/syscall/mod.rs +++ b/crates/kernel/src/syscall/mod.rs @@ -35,7 +35,6 @@ pub unsafe fn register_syscalls() { register_syscall_handler(21, time::sys_get_time_ms); register_syscall_handler(22, time::sys_sleep_ms); - register_syscall_handler(23, fb_hack::sys_acquire_fb); register_syscall_handler(24, fb_hack::sys_memfd_create); register_syscall_handler(25, fb_hack::sys_poll_key_event); diff --git a/crates/ulib/src/sys.rs b/crates/ulib/src/sys.rs index 05b302f5..b17e3d35 100644 --- a/crates/ulib/src/sys.rs +++ b/crates/ulib/src/sys.rs @@ -84,6 +84,7 @@ syscall!(21 => pub fn sys_get_time_ms() -> usize); syscall!(22 => pub fn sys_sleep_ms(time: usize)); // syscall!(23 => pub fn sys_acquire_fb(width: usize, height: usize) -> (usize, usize, usize, usize, usize)); + #[repr(C)] pub struct RawFB { pub fd: usize, @@ -122,6 +123,46 @@ syscall!(26 => pub fn sys_sem_create(value: usize) -> isize); syscall!(27 => pub fn sys_sem_up(fd: usize) -> isize); syscall!(28 => pub fn sys_sem_down(fd: usize) -> isize); +core::arch::global_asm!( + ".global {name}; {name}:", + "mov x0, lr", //Read link register value into x0 + "svc #{num}", + "ret", + name = sym sys_fork_helper, + num = const 5, +); +unsafe extern "C" { + fn sys_fork_helper(pc: usize, sp: usize, x0: usize, flags: usize) -> isize; +} + +//saves and restores callee saved registers +core::arch::global_asm!( + ".global {name}; {name}:", + "sub sp, sp, #0x60", + "stp x19, x20, [sp, #0x50]", + "stp x21, x22, [sp, #0x40]", + "stp x23, x24, [sp, #0x30]", + "stp x25, x26, [sp, #0x20]", + "stp x27, x28, [sp, #0x10]", + "stp x29, x30, [sp]", + "mov x1, sp", + "mov x2, 0", //child should get 0 + "mov x3, 0", + "bl sys_fork_helper", + "ldp x29, x30, [sp]", + "ldp x27, x28, [sp, #0x10]", + "ldp x25, x26, [sp, #0x20]", + "ldp x23, x24, [sp, #0x30]", + "ldp x21, x22, [sp, #0x40]", + "ldp x19, x20, [sp, #0x50]", + "add sp, sp, #0x60", + "ret", + name = sym sys_fork, +); +unsafe extern "C" { + pub fn sys_fork() -> isize; +} + /* * * * * * * * * * * * * * * * * * * */ /* Syscall wrappers */ /* * * * * * * * * * * * * * * * * * * */ @@ -259,6 +300,12 @@ pub fn wait(fd: FileDesc) -> Result { int_to_error(res) } +pub const MAP_PRIVATE: u32 = 0; +pub const MAP_FILE: u32 = 0; //linux mmap ignores this but can have it for readabilty? +pub const MAP_FIXED: u32 = 1 << 0; +pub const MAP_ANONYMOUS: u32 = 1 << 1; +pub const MAP_SHARED: u32 = 1 << 2; + pub unsafe fn mmap( addr: usize, size: usize,