forked from Bananymous/banan-os
update main #1
|
@ -15,6 +15,7 @@
|
||||||
#include <kernel/Terminal/TTY.h>
|
#include <kernel/Terminal/TTY.h>
|
||||||
#include <kernel/Thread.h>
|
#include <kernel/Thread.h>
|
||||||
|
|
||||||
|
#include <sys/mman.h>
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
|
|
||||||
namespace LibELF { class ELF; }
|
namespace LibELF { class ELF; }
|
||||||
|
@ -115,6 +116,9 @@ namespace Kernel
|
||||||
|
|
||||||
BAN::ErrorOr<long> sys_read_dir_entries(int fd, DirectoryEntryList* buffer, size_t buffer_size);
|
BAN::ErrorOr<long> sys_read_dir_entries(int fd, DirectoryEntryList* buffer, size_t buffer_size);
|
||||||
|
|
||||||
|
BAN::ErrorOr<long> sys_mmap(const sys_mmap_t&);
|
||||||
|
BAN::ErrorOr<long> sys_munmap(void* addr, size_t len);
|
||||||
|
|
||||||
BAN::ErrorOr<long> sys_alloc(size_t);
|
BAN::ErrorOr<long> sys_alloc(size_t);
|
||||||
BAN::ErrorOr<long> sys_free(void*);
|
BAN::ErrorOr<long> sys_free(void*);
|
||||||
|
|
||||||
|
@ -177,6 +181,8 @@ namespace Kernel
|
||||||
BAN::String m_working_directory;
|
BAN::String m_working_directory;
|
||||||
BAN::Vector<Thread*> m_threads;
|
BAN::Vector<Thread*> m_threads;
|
||||||
|
|
||||||
|
BAN::Vector<BAN::UniqPtr<VirtualRange>> m_private_anonymous_mappings;
|
||||||
|
|
||||||
BAN::Vector<BAN::UniqPtr<FixedWidthAllocator>> m_fixed_width_allocators;
|
BAN::Vector<BAN::UniqPtr<FixedWidthAllocator>> m_fixed_width_allocators;
|
||||||
BAN::UniqPtr<GeneralAllocator> m_general_allocator;
|
BAN::UniqPtr<GeneralAllocator> m_general_allocator;
|
||||||
|
|
||||||
|
|
|
@ -159,6 +159,7 @@ namespace Kernel
|
||||||
ASSERT(m_threads.empty());
|
ASSERT(m_threads.empty());
|
||||||
ASSERT(m_fixed_width_allocators.empty());
|
ASSERT(m_fixed_width_allocators.empty());
|
||||||
ASSERT(!m_general_allocator);
|
ASSERT(!m_general_allocator);
|
||||||
|
ASSERT(m_private_anonymous_mappings.empty());
|
||||||
ASSERT(m_mapped_ranges.empty());
|
ASSERT(m_mapped_ranges.empty());
|
||||||
ASSERT(m_exit_status.waiting == 0);
|
ASSERT(m_exit_status.waiting == 0);
|
||||||
ASSERT(&PageTable::current() != m_page_table.ptr());
|
ASSERT(&PageTable::current() != m_page_table.ptr());
|
||||||
|
@ -192,6 +193,7 @@ namespace Kernel
|
||||||
m_open_file_descriptors.close_all();
|
m_open_file_descriptors.close_all();
|
||||||
|
|
||||||
// NOTE: We must unmap ranges while the page table is still alive
|
// NOTE: We must unmap ranges while the page table is still alive
|
||||||
|
m_private_anonymous_mappings.clear();
|
||||||
m_mapped_ranges.clear();
|
m_mapped_ranges.clear();
|
||||||
|
|
||||||
// NOTE: We must clear allocators while the page table is still alive
|
// NOTE: We must clear allocators while the page table is still alive
|
||||||
|
@ -358,6 +360,11 @@ namespace Kernel
|
||||||
OpenFileDescriptorSet open_file_descriptors(m_credentials);
|
OpenFileDescriptorSet open_file_descriptors(m_credentials);
|
||||||
TRY(open_file_descriptors.clone_from(m_open_file_descriptors));
|
TRY(open_file_descriptors.clone_from(m_open_file_descriptors));
|
||||||
|
|
||||||
|
BAN::Vector<BAN::UniqPtr<VirtualRange>> private_anonymous_mappings;
|
||||||
|
TRY(private_anonymous_mappings.reserve(m_private_anonymous_mappings.size()));
|
||||||
|
for (auto& private_anonymous_mapping : m_private_anonymous_mappings)
|
||||||
|
MUST(private_anonymous_mappings.push_back(TRY(private_anonymous_mapping->clone(*page_table))));
|
||||||
|
|
||||||
BAN::Vector<BAN::UniqPtr<VirtualRange>> mapped_ranges;
|
BAN::Vector<BAN::UniqPtr<VirtualRange>> mapped_ranges;
|
||||||
TRY(mapped_ranges.reserve(m_mapped_ranges.size()));
|
TRY(mapped_ranges.reserve(m_mapped_ranges.size()));
|
||||||
for (auto& mapped_range : m_mapped_ranges)
|
for (auto& mapped_range : m_mapped_ranges)
|
||||||
|
@ -378,6 +385,7 @@ namespace Kernel
|
||||||
forked->m_working_directory = BAN::move(working_directory);
|
forked->m_working_directory = BAN::move(working_directory);
|
||||||
forked->m_page_table = BAN::move(page_table);
|
forked->m_page_table = BAN::move(page_table);
|
||||||
forked->m_open_file_descriptors = BAN::move(open_file_descriptors);
|
forked->m_open_file_descriptors = BAN::move(open_file_descriptors);
|
||||||
|
forked->m_private_anonymous_mappings = BAN::move(private_anonymous_mappings);
|
||||||
forked->m_mapped_ranges = BAN::move(mapped_ranges);
|
forked->m_mapped_ranges = BAN::move(mapped_ranges);
|
||||||
forked->m_fixed_width_allocators = BAN::move(fixed_width_allocators);
|
forked->m_fixed_width_allocators = BAN::move(fixed_width_allocators);
|
||||||
forked->m_general_allocator = BAN::move(general_allocator);
|
forked->m_general_allocator = BAN::move(general_allocator);
|
||||||
|
@ -428,6 +436,7 @@ namespace Kernel
|
||||||
|
|
||||||
m_fixed_width_allocators.clear();
|
m_fixed_width_allocators.clear();
|
||||||
m_general_allocator.clear();
|
m_general_allocator.clear();
|
||||||
|
m_private_anonymous_mappings.clear();
|
||||||
m_mapped_ranges.clear();
|
m_mapped_ranges.clear();
|
||||||
|
|
||||||
load_elf_to_memory(*elf);
|
load_elf_to_memory(*elf);
|
||||||
|
@ -811,6 +820,66 @@ namespace Kernel
|
||||||
return (long)buffer;
|
return (long)buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BAN::ErrorOr<long> Process::sys_mmap(const sys_mmap_t& args)
|
||||||
|
{
|
||||||
|
if (args.prot != PROT_NONE && args.prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC))
|
||||||
|
return BAN::Error::from_errno(EINVAL);
|
||||||
|
|
||||||
|
PageTable::flags_t flags = PageTable::Flags::UserSupervisor;
|
||||||
|
if (args.prot & PROT_READ)
|
||||||
|
flags |= PageTable::Flags::Present;
|
||||||
|
if (args.prot & PROT_WRITE)
|
||||||
|
flags |= PageTable::Flags::ReadWrite | PageTable::Flags::Present;
|
||||||
|
if (args.prot & PROT_EXEC)
|
||||||
|
flags |= PageTable::Flags::Execute | PageTable::Flags::Present;
|
||||||
|
|
||||||
|
if (args.flags == (MAP_ANONYMOUS | MAP_PRIVATE))
|
||||||
|
{
|
||||||
|
if (args.addr != nullptr)
|
||||||
|
return BAN::Error::from_errno(ENOTSUP);
|
||||||
|
if (args.off != 0)
|
||||||
|
return BAN::Error::from_errno(EINVAL);
|
||||||
|
if (args.len % PAGE_SIZE != 0)
|
||||||
|
return BAN::Error::from_errno(EINVAL);
|
||||||
|
|
||||||
|
auto range = TRY(VirtualRange::create_to_vaddr_range(
|
||||||
|
page_table(),
|
||||||
|
0x400000, KERNEL_OFFSET,
|
||||||
|
args.len,
|
||||||
|
PageTable::Flags::UserSupervisor | PageTable::Flags::ReadWrite | PageTable::Flags::Present
|
||||||
|
));
|
||||||
|
range->set_zero();
|
||||||
|
|
||||||
|
LockGuard _(m_lock);
|
||||||
|
TRY(m_private_anonymous_mappings.push_back(BAN::move(range)));
|
||||||
|
return m_private_anonymous_mappings.back()->vaddr();
|
||||||
|
}
|
||||||
|
|
||||||
|
return BAN::Error::from_errno(ENOTSUP);
|
||||||
|
}
|
||||||
|
|
||||||
|
BAN::ErrorOr<long> Process::sys_munmap(void* addr, size_t len)
|
||||||
|
{
|
||||||
|
if (len == 0)
|
||||||
|
return BAN::Error::from_errno(EINVAL);
|
||||||
|
|
||||||
|
vaddr_t vaddr = (vaddr_t)addr;
|
||||||
|
if (vaddr % PAGE_SIZE != 0)
|
||||||
|
return BAN::Error::from_errno(EINVAL);
|
||||||
|
|
||||||
|
LockGuard _(m_lock);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < m_private_anonymous_mappings.size(); i++)
|
||||||
|
{
|
||||||
|
auto& mapping = m_private_anonymous_mappings[i];
|
||||||
|
if (vaddr + len < mapping->vaddr() || vaddr >= mapping->vaddr() + mapping->size())
|
||||||
|
continue;
|
||||||
|
m_private_anonymous_mappings.remove(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static constexpr size_t allocator_size_for_allocation(size_t value)
|
static constexpr size_t allocator_size_for_allocation(size_t value)
|
||||||
{
|
{
|
||||||
if (value <= 256) {
|
if (value <= 256) {
|
||||||
|
|
|
@ -194,6 +194,12 @@ namespace Kernel
|
||||||
case SYS_SYNC:
|
case SYS_SYNC:
|
||||||
ret = Process::current().sys_sync();
|
ret = Process::current().sys_sync();
|
||||||
break;
|
break;
|
||||||
|
case SYS_MMAP:
|
||||||
|
ret = Process::current().sys_mmap(*(const sys_mmap_t*)arg1);
|
||||||
|
break;
|
||||||
|
case SYS_MUNMAP:
|
||||||
|
ret = Process::current().sys_munmap((void*)arg1, (size_t)arg2);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
dwarnln("Unknown syscall {}", syscall);
|
dwarnln("Unknown syscall {}", syscall);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -13,6 +13,7 @@ set(LIBC_SOURCES
|
||||||
stdio.cpp
|
stdio.cpp
|
||||||
stdlib.cpp
|
stdlib.cpp
|
||||||
string.cpp
|
string.cpp
|
||||||
|
sys/mman.cpp
|
||||||
sys/stat.cpp
|
sys/stat.cpp
|
||||||
sys/wait.cpp
|
sys/wait.cpp
|
||||||
termios.cpp
|
termios.cpp
|
||||||
|
|
|
@ -46,6 +46,16 @@ struct posix_typed_mem_info
|
||||||
size_t posix_tmi_length; /* Maximum length which may be allocated from a typed memory object. */
|
size_t posix_tmi_length; /* Maximum length which may be allocated from a typed memory object. */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct sys_mmap_t
|
||||||
|
{
|
||||||
|
void* addr;
|
||||||
|
size_t len;
|
||||||
|
int prot;
|
||||||
|
int flags;
|
||||||
|
int fildes;
|
||||||
|
off_t off;
|
||||||
|
};
|
||||||
|
|
||||||
int mlock(const void* addr, size_t len);
|
int mlock(const void* addr, size_t len);
|
||||||
int mlockall(int flags);
|
int mlockall(int flags);
|
||||||
void* mmap(void* addr, size_t len, int prot, int flags, int fildes, off_t off);
|
void* mmap(void* addr, size_t len, int prot, int flags, int fildes, off_t off);
|
||||||
|
|
|
@ -55,6 +55,8 @@ __BEGIN_DECLS
|
||||||
#define SYS_FSTATAT 48
|
#define SYS_FSTATAT 48
|
||||||
#define SYS_STAT 49 // stat/lstat
|
#define SYS_STAT 49 // stat/lstat
|
||||||
#define SYS_SYNC 50
|
#define SYS_SYNC 50
|
||||||
|
#define SYS_MMAP 51
|
||||||
|
#define SYS_MUNMAP 52
|
||||||
|
|
||||||
__END_DECLS
|
__END_DECLS
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
void* mmap(void* addr, size_t len, int prot, int flags, int fildes, off_t off)
|
||||||
|
{
|
||||||
|
sys_mmap_t args {
|
||||||
|
.addr = addr,
|
||||||
|
.len = len,
|
||||||
|
.prot = prot,
|
||||||
|
.flags = flags,
|
||||||
|
.off = off
|
||||||
|
};
|
||||||
|
long ret = syscall(SYS_MMAP, &args);
|
||||||
|
if (ret == -1)
|
||||||
|
return nullptr;
|
||||||
|
return (void*)ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int munmap(void* addr, size_t len)
|
||||||
|
{
|
||||||
|
return syscall(SYS_MUNMAP, addr, len);
|
||||||
|
}
|
Loading…
Reference in New Issue