forked from Bananymous/banan-os
Kernel: Add API for implementing mmappable devices
This commit is contained in:
parent
d86ecf4f61
commit
4a87d6052b
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <kernel/FS/TmpFS/Inode.h>
|
#include <kernel/FS/TmpFS/Inode.h>
|
||||||
|
#include <kernel/Memory/MemoryRegion.h>
|
||||||
|
|
||||||
namespace Kernel
|
namespace Kernel
|
||||||
{
|
{
|
||||||
|
@ -15,6 +16,8 @@ namespace Kernel
|
||||||
virtual bool is_partition() const { return false; }
|
virtual bool is_partition() const { return false; }
|
||||||
virtual bool is_storage_device() const { return false; }
|
virtual bool is_storage_device() const { return false; }
|
||||||
|
|
||||||
|
virtual BAN::ErrorOr<BAN::UniqPtr<MemoryRegion>> mmap_region(PageTable&, off_t offset, size_t len, AddressRange, MemoryRegion::Type, PageTable::flags_t) { return BAN::Error::from_errno(EINVAL); }
|
||||||
|
|
||||||
virtual dev_t rdev() const override = 0;
|
virtual dev_t rdev() const override = 0;
|
||||||
|
|
||||||
virtual BAN::StringView name() const = 0;
|
virtual BAN::StringView name() const = 0;
|
||||||
|
|
|
@ -1058,33 +1058,46 @@ namespace Kernel
|
||||||
return m_mapped_regions.back()->vaddr();
|
return m_mapped_regions.back()->vaddr();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto inode = TRY(m_open_file_descriptors.inode_of(args->fildes));
|
if (args->addr != nullptr)
|
||||||
if (inode->mode().ifreg())
|
return BAN::Error::from_errno(ENOTSUP);
|
||||||
{
|
|
||||||
if (args->addr != nullptr)
|
|
||||||
return BAN::Error::from_errno(ENOTSUP);
|
|
||||||
|
|
||||||
auto inode_flags = TRY(m_open_file_descriptors.flags_of(args->fildes));
|
LockGuard _(m_lock);
|
||||||
if (!(inode_flags & O_RDONLY))
|
|
||||||
|
auto inode = TRY(m_open_file_descriptors.inode_of(args->fildes));
|
||||||
|
|
||||||
|
auto inode_flags = TRY(m_open_file_descriptors.flags_of(args->fildes));
|
||||||
|
if (!(inode_flags & O_RDONLY))
|
||||||
|
return BAN::Error::from_errno(EACCES);
|
||||||
|
if (region_type == MemoryRegion::Type::SHARED)
|
||||||
|
if ((args->prot & PROT_WRITE) && !(inode_flags & O_WRONLY))
|
||||||
return BAN::Error::from_errno(EACCES);
|
return BAN::Error::from_errno(EACCES);
|
||||||
if (region_type == MemoryRegion::Type::SHARED)
|
|
||||||
if ((args->prot & PROT_WRITE) && !(inode_flags & O_WRONLY))
|
BAN::UniqPtr<MemoryRegion> memory_region;
|
||||||
return BAN::Error::from_errno(EACCES);
|
if (inode->mode().ifreg())
|
||||||
|
{
|
||||||
auto region = TRY(FileBackedRegion::create(
|
memory_region = TRY(FileBackedRegion::create(
|
||||||
inode,
|
inode,
|
||||||
page_table(),
|
page_table(),
|
||||||
args->off, args->len,
|
args->off, args->len,
|
||||||
{ .start = 0x400000, .end = KERNEL_OFFSET },
|
{ .start = 0x400000, .end = KERNEL_OFFSET },
|
||||||
region_type, page_flags
|
region_type, page_flags
|
||||||
));
|
));
|
||||||
|
|
||||||
LockGuard _(m_lock);
|
|
||||||
TRY(m_mapped_regions.push_back(BAN::move(region)));
|
|
||||||
return m_mapped_regions.back()->vaddr();
|
|
||||||
}
|
}
|
||||||
|
else if (inode->is_device())
|
||||||
|
{
|
||||||
|
memory_region = TRY(static_cast<Device&>(*inode).mmap_region(
|
||||||
|
page_table(),
|
||||||
|
args->off, args->len,
|
||||||
|
{ .start = 0x400000, .end = KERNEL_OFFSET },
|
||||||
|
region_type, page_flags
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!memory_region)
|
||||||
|
return BAN::Error::from_errno(ENODEV);
|
||||||
|
|
||||||
return BAN::Error::from_errno(ENOTSUP);
|
TRY(m_mapped_regions.push_back(BAN::move(memory_region)));
|
||||||
|
return m_mapped_regions.back()->vaddr();
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<long> Process::sys_munmap(void* addr, size_t len)
|
BAN::ErrorOr<long> Process::sys_munmap(void* addr, size_t len)
|
||||||
|
|
Loading…
Reference in New Issue