Browse Source

Add simplified mmap() and munmap() syscalls.

Andreas Kling 6 years ago
parent
commit
9a296d63f3
13 changed files with 116 additions and 2 deletions
  1. 5 0
      .gitignore
  2. 4 0
      Kernel/Syscall.cpp
  3. 2 0
      Kernel/Syscall.h
  4. 43 0
      Kernel/Task.cpp
  5. 5 0
      Kernel/Task.h
  6. BIN
      Kernel/_fs_contents
  7. 1 0
      Kernel/sync-sh
  8. 1 0
      LibC/Makefile
  9. 16 0
      LibC/mman.cpp
  10. 10 0
      LibC/mman.h
  11. 1 0
      Userland/.gitignore
  12. 7 2
      Userland/Makefile
  13. 21 0
      Userland/ls.cpp

+ 5 - 0
.gitignore

@@ -1 +1,6 @@
 *.swp
 *.swp
+Serenity.config
+Serenity.creator
+Serenity.creator.user
+Serenity.files
+Serenity.includes

+ 4 - 0
Kernel/Syscall.cpp

@@ -90,6 +90,10 @@ DWORD handle(DWORD function, DWORD arg1, DWORD arg2, DWORD arg3)
         return current->sys$getpid();
         return current->sys$getpid();
     case Syscall::PosixWaitpid:
     case Syscall::PosixWaitpid:
         return current->sys$waitpid((pid_t)arg1);
         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:
     case Syscall::PosixExit:
         cli();
         cli();
         locker.unlock();
         locker.unlock();

+ 2 - 0
Kernel/Syscall.h

@@ -24,6 +24,8 @@ enum Function {
     PosixGetgid = 0x1992,
     PosixGetgid = 0x1992,
     PosixGetpid = 0x1993,
     PosixGetpid = 0x1993,
     PosixWaitpid = 0x1994,
     PosixWaitpid = 0x1994,
+    PosixMmap = 0x1995,
+    PosixMunmap = 0x1996,
 };
 };
 
 
 void initialize();
 void initialize();

+ 43 - 0
Kernel/Task.cpp

@@ -120,6 +120,49 @@ Task::Region* Task::allocateRegion(size_t size, String&& name)
     return m_regions.last().ptr();
     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() == &region) {
+            // 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)
 int Task::sys$spawn(const char* path)
 {
 {
     auto* child = Task::create(path, m_uid, m_gid);
     auto* child = Task::create(path, m_uid, m_gid);

+ 5 - 0
Kernel/Task.h

@@ -99,6 +99,8 @@ public:
     void sys$exit(int status);
     void sys$exit(int status);
     int sys$spawn(const char* path);
     int sys$spawn(const char* path);
     pid_t sys$waitpid(pid_t);
     pid_t sys$waitpid(pid_t);
+    void* sys$mmap(void*, size_t size);
+    int sys$munmap(void*, size_t size);
 
 
     struct
     struct
     {
     {
@@ -160,6 +162,9 @@ private:
         String name;
         String name;
     };
     };
     Region* allocateRegion(size_t, String&& name);
     Region* allocateRegion(size_t, String&& name);
+    bool deallocateRegion(Region& region);
+
+    Region* regionFromRange(LinearAddress, size_t);
 
 
     Vector<OwnPtr<Region>> m_regions;
     Vector<OwnPtr<Region>> m_regions;
 
 

BIN
Kernel/_fs_contents


+ 1 - 0
Kernel/sync-sh

@@ -3,5 +3,6 @@ mount -o loop _fs_contents mnt/
 cp ../Userland/sh mnt/bin/sh
 cp ../Userland/sh mnt/bin/sh
 cp ../Userland/id mnt/bin/id
 cp ../Userland/id mnt/bin/id
 cp ../Userland/ps mnt/bin/ps
 cp ../Userland/ps mnt/bin/ps
+cp ../Userland/ls mnt/bin/ls
 umount mnt
 umount mnt
 sync
 sync

+ 1 - 0
LibC/Makefile

@@ -3,6 +3,7 @@ OBJS = \
        unistd.o \
        unistd.o \
        string.o \
        string.o \
        process.o \
        process.o \
+       mman.o \
        entry.o
        entry.o
 
 
 LIBRARY = LibC.a
 LIBRARY = LibC.a

+ 16 - 0
LibC/mman.cpp

@@ -0,0 +1,16 @@
+#include "mman.h"
+#include <Kernel/Syscall.h>
+
+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);
+}
+
+}

+ 10 - 0
LibC/mman.h

@@ -0,0 +1,10 @@
+#pragma once
+
+#include "types.h"
+
+extern "C" {
+
+void* mmap(void*, size_t);
+int munmap(void*, size_t);
+
+}

+ 1 - 0
Userland/.gitignore

@@ -1,4 +1,5 @@
 id
 id
 sh
 sh
 ps
 ps
+ls
 *.o
 *.o

+ 7 - 2
Userland/Makefile

@@ -1,12 +1,14 @@
 OBJS = \
 OBJS = \
        id.o \
        id.o \
        sh.o \
        sh.o \
-       ps.o
+       ps.o \
+       ls.o
 
 
 APPS = \
 APPS = \
        id \
        id \
        sh \
        sh \
-       ps
+       ps \
+       ls
 
 
 ARCH_FLAGS =
 ARCH_FLAGS =
 STANDARD_FLAGS = -std=c++17 -nostdinc++ -nostdlib
 STANDARD_FLAGS = -std=c++17 -nostdinc++ -nostdlib
@@ -35,6 +37,9 @@ sh: sh.o
 ps: ps.o
 ps: ps.o
 	$(LD) -o $@ $(LDFLAGS) $< ../LibC/LibC.a
 	$(LD) -o $@ $(LDFLAGS) $< ../LibC/LibC.a
 
 
+ls: ls.o
+	$(LD) -o $@ $(LDFLAGS) $< ../LibC/LibC.a
+
 .cpp.o:
 .cpp.o:
 	@echo "CXX $<"; $(CXX) $(CXXFLAGS) -o $@ -c $<
 	@echo "CXX $<"; $(CXX) $(CXXFLAGS) -o $@ -c $<
 
 

+ 21 - 0
Userland/ls.cpp

@@ -0,0 +1,21 @@
+#include <LibC/stdio.h>
+#include <LibC/unistd.h>
+#include <LibC/mman.h>
+
+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;
+}