update main #1

Merged
Sinipelto merged 240 commits from Bananymous/banan-os:main into main 2023-11-20 13:20:51 +02:00
7 changed files with 117 additions and 0 deletions
Showing only changes of commit fee3677fb9 - Show all commits

View File

@ -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;

View File

@ -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) {

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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

23
libc/sys/mman.cpp Normal file
View File

@ -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);
}