From 9a296d63f3c89eb1d4e123d322e4c3fb4e6cf18f Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Wed, 24 Oct 2018 09:48:24 +0200 Subject: [PATCH] Add simplified mmap() and munmap() syscalls. --- .gitignore | 5 +++++ Kernel/Syscall.cpp | 4 ++++ Kernel/Syscall.h | 2 ++ Kernel/Task.cpp | 43 +++++++++++++++++++++++++++++++++++++++++++ Kernel/Task.h | 5 +++++ Kernel/_fs_contents | Bin 1024000 -> 1024000 bytes Kernel/sync-sh | 1 + LibC/Makefile | 1 + LibC/mman.cpp | 16 ++++++++++++++++ LibC/mman.h | 10 ++++++++++ Userland/.gitignore | 1 + Userland/Makefile | 9 +++++++-- Userland/ls.cpp | 21 +++++++++++++++++++++ 13 files changed, 116 insertions(+), 2 deletions(-) create mode 100644 LibC/mman.cpp create mode 100644 LibC/mman.h create mode 100644 Userland/ls.cpp diff --git a/.gitignore b/.gitignore index 1377554ebe..11d77b9424 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,6 @@ *.swp +Serenity.config +Serenity.creator +Serenity.creator.user +Serenity.files +Serenity.includes diff --git a/Kernel/Syscall.cpp b/Kernel/Syscall.cpp index a5701b452f..1e70f9a510 100644 --- a/Kernel/Syscall.cpp +++ b/Kernel/Syscall.cpp @@ -90,6 +90,10 @@ DWORD handle(DWORD function, DWORD arg1, DWORD arg2, DWORD arg3) return current->sys$getpid(); case Syscall::PosixWaitpid: return current->sys$waitpid((pid_t)arg1); + case Syscall::PosixMmap: + return (dword)current->sys$mmap((void*)arg1, (size_t)arg2); + case Syscall::PosixMunmap: + return current->sys$munmap((void*)arg1, (size_t)arg2); case Syscall::PosixExit: cli(); locker.unlock(); diff --git a/Kernel/Syscall.h b/Kernel/Syscall.h index edc24d610b..22f6fb3812 100644 --- a/Kernel/Syscall.h +++ b/Kernel/Syscall.h @@ -24,6 +24,8 @@ enum Function { PosixGetgid = 0x1992, PosixGetpid = 0x1993, PosixWaitpid = 0x1994, + PosixMmap = 0x1995, + PosixMunmap = 0x1996, }; void initialize(); diff --git a/Kernel/Task.cpp b/Kernel/Task.cpp index 564ba726f9..4382b8db73 100644 --- a/Kernel/Task.cpp +++ b/Kernel/Task.cpp @@ -120,6 +120,49 @@ Task::Region* Task::allocateRegion(size_t size, String&& name) return m_regions.last().ptr(); } +bool Task::deallocateRegion(Region& region) +{ + for (size_t i = 0; i < m_regions.size(); ++i) { + if (m_regions[i].ptr() == ®ion) { + // FIXME: This seems racy. + MemoryManager::the().unmapRegion(*this, region); + m_regions.remove(i); + return true; + } + } + return false; +} + +Task::Region* Task::regionFromRange(LinearAddress laddr, size_t size) +{ + for (auto& region : m_regions) { + if (region->linearAddress == laddr && region->size == size) + return region.ptr(); + } + return nullptr; +} + +void* Task::sys$mmap(void* addr, size_t size) +{ + // FIXME: Implement mapping at a client-preferred address. + ASSERT(addr == nullptr); + auto* region = allocateRegion(size, "mmap"); + if (!region) + return (void*)-1; + MemoryManager::the().mapRegion(*this, *region); + return (void*)region->linearAddress.get(); +} + +int Task::sys$munmap(void* addr, size_t size) +{ + auto* region = regionFromRange(LinearAddress((dword)addr), size); + if (!region) + return -1; + if (!deallocateRegion(*region)) + return -1; + return 0; +} + int Task::sys$spawn(const char* path) { auto* child = Task::create(path, m_uid, m_gid); diff --git a/Kernel/Task.h b/Kernel/Task.h index 7427daee80..f79ccc267d 100644 --- a/Kernel/Task.h +++ b/Kernel/Task.h @@ -99,6 +99,8 @@ public: void sys$exit(int status); int sys$spawn(const char* path); pid_t sys$waitpid(pid_t); + void* sys$mmap(void*, size_t size); + int sys$munmap(void*, size_t size); struct { @@ -160,6 +162,9 @@ private: String name; }; Region* allocateRegion(size_t, String&& name); + bool deallocateRegion(Region& region); + + Region* regionFromRange(LinearAddress, size_t); Vector> m_regions; diff --git a/Kernel/_fs_contents b/Kernel/_fs_contents index 70277d8a7b6b46678562f84003bee4969fa4821e..315825570efed2d33dad720c6d561cae18cbe31b 100644 GIT binary patch delta 1713 zcmZ8hZA@EL7=F*~E!;w(?JZC$gx<12!C@)5PQC|WCTvD67=p=+vk^8(fEBsuj36Ye z&6(^=>%yI z)3a$C+T>($+?0D5G9&3I{nM08d*&SOol=HR0D%W()3A*=6ZRTyqpqrMcN76Dk0NM; zh(n0y5Dkb%L{ozJwEp_9_LL`(gHASxR$bqmu#3t5XRCx~_Lk2?VPrAx$c=akQGzJd z>H-I}jo@eVm15(^1pqtA%<8pa_x>E1BqN-N0z@IA2#ff{p-%6Sg#VDjL23H zNMszqk40{o1Ts9nK$cC{x0K?~m0t^@3W+L0R53*rF{+rON>)_K{z8$COn2FgRS)W> z3d+F?eRGrhrP+S^V4WMEXORhp`Dpdz9)DHY?%!@oTwq=;T{TWaY~ zQAwuT7GkH7PbE7I1&N=O(CHv)oW>o22!E$L*aSx&LPq7N&OrahGT5P;b4mB-z*){8 zgRzb$=n8;M|DMg_FCu1x5@$jip(E0(grDl<8cCcR4TCc|N?)d06KH%yO<^ zBgv2r=Q+>U{SKJtyhP_#pq#VkC zGStt^1RC^4=u9rDVRz*~5d0}ZE7SnK4ue-RUJlU0ERthff0^rDjLQIKye@+8Jiu)q zx9klu{RX$}x{1?h7^WXX{b@FNn+Kfb_B(Fz{eW-)fZexHom{@xD-@{%XH-AiKKPBP zemwg1nDl}+^`uk#=1D6F(}a!ev)s-#`rSjnZ6Y3Wi9To|K5|8SaotBlA4n4MXjAJR z@`-kN-DhdQe~bXGOq>oGGguPdoj%Uda4T^&=A&joq1{m73@*-^-GgAQDwGeAJww`yQl`N=PdE%3oq(9)(rs!EuyDQCKTl}XDaiyw1kbV>m~w&mO_jR zl@xoC(wuuM>)%w^mQ)EFT*^?!P|i@H*m5$|W_z0O-?mB?tzy{6u%F=oZ&T*;2PUp` zA?NP##yp4ql_(%b#~7Lt$CpX;H8LINCdf?$Hxb=L=O!U;qIZ+f>jYQcCFoP^y`z}u zq6#9{zb-FGX|M}Y6#H~LBFc^Fy@okfb*%_J=9-$r%D3qpbdy?r_;``Iw)Rjh)k5-d--m(~J-&4|ta^)w5st;>UYQs-JWd!O7t6A$p*>3v$$!q*48 zyzg9-arJ$6WSuyF5uZi4!_nDBQci~X5TP{$4O3M6Q$CT%Q&_-1%Qu6?22|W z7P0~IHC@Ox^AB=n57Nvz9iUzFJ2ju*3GeUI^oXWaO+VwD1Q5o4A)bq2EMx*CFwPRv z*h0-H`4Rb?CS^F)~s;ju0 zt{G9Np~KPC*_PcQx7)I9^mPHQRQz8WrI`o-!Wxrl>o87c_u^wDt+MK9u=;2iThSZ( zVHl^P&&uP4ROyZpAcuR(j|D4wuUHmSrJ2oI*`n1WV~;F(sM?vV{1Il?0wZ^)+1 EzrH#A9smFU diff --git a/Kernel/sync-sh b/Kernel/sync-sh index 971ab5c9cb..a0f071bd68 100755 --- a/Kernel/sync-sh +++ b/Kernel/sync-sh @@ -3,5 +3,6 @@ mount -o loop _fs_contents mnt/ cp ../Userland/sh mnt/bin/sh cp ../Userland/id mnt/bin/id cp ../Userland/ps mnt/bin/ps +cp ../Userland/ls mnt/bin/ls umount mnt sync diff --git a/LibC/Makefile b/LibC/Makefile index 47485d29fd..ed1e157531 100644 --- a/LibC/Makefile +++ b/LibC/Makefile @@ -3,6 +3,7 @@ OBJS = \ unistd.o \ string.o \ process.o \ + mman.o \ entry.o LIBRARY = LibC.a diff --git a/LibC/mman.cpp b/LibC/mman.cpp new file mode 100644 index 0000000000..ad8aae334c --- /dev/null +++ b/LibC/mman.cpp @@ -0,0 +1,16 @@ +#include "mman.h" +#include + +extern "C" { + +void* mmap(void* addr, size_t size) +{ + return (void*)Syscall::invoke(Syscall::PosixMmap, (dword)addr, (dword)size); +} + +int munmap(void* addr, size_t size) +{ + return Syscall::invoke(Syscall::PosixMunmap, (dword)addr, (dword)size); +} + +} diff --git a/LibC/mman.h b/LibC/mman.h new file mode 100644 index 0000000000..fb6f2af844 --- /dev/null +++ b/LibC/mman.h @@ -0,0 +1,10 @@ +#pragma once + +#include "types.h" + +extern "C" { + +void* mmap(void*, size_t); +int munmap(void*, size_t); + +} diff --git a/Userland/.gitignore b/Userland/.gitignore index 27529b9b9b..5f641bf9a1 100644 --- a/Userland/.gitignore +++ b/Userland/.gitignore @@ -1,4 +1,5 @@ id sh ps +ls *.o diff --git a/Userland/Makefile b/Userland/Makefile index ec3fddd381..c1cd22033c 100644 --- a/Userland/Makefile +++ b/Userland/Makefile @@ -1,12 +1,14 @@ OBJS = \ id.o \ sh.o \ - ps.o + ps.o \ + ls.o APPS = \ id \ sh \ - ps + ps \ + ls ARCH_FLAGS = STANDARD_FLAGS = -std=c++17 -nostdinc++ -nostdlib @@ -35,6 +37,9 @@ sh: sh.o ps: ps.o $(LD) -o $@ $(LDFLAGS) $< ../LibC/LibC.a +ls: ls.o + $(LD) -o $@ $(LDFLAGS) $< ../LibC/LibC.a + .cpp.o: @echo "CXX $<"; $(CXX) $(CXXFLAGS) -o $@ -c $< diff --git a/Userland/ls.cpp b/Userland/ls.cpp new file mode 100644 index 0000000000..f6a90568b9 --- /dev/null +++ b/Userland/ls.cpp @@ -0,0 +1,21 @@ +#include +#include +#include + +int main(int c, char** v) +{ + int fd = open("/"); + if (fd == -1) { + printf("failed to open / :(\n"); + return 1; + } + + byte* memory = (byte*)mmap(nullptr, 16384); + printf("%p\n", memory); + memory[0] = 'H'; + memory[1] = 'i'; + memory[2] = '!'; + memory[3] = '\0'; + printf("%p : %s\n", memory, memory); + return 0; +}