Compare commits
2 Commits
71633e264f
...
e5b2641019
Author | SHA1 | Date | |
---|---|---|---|
e5b2641019 | |||
2c08de044f |
@ -1,12 +1,12 @@
|
|||||||
#include "fs/devices/Framebuffer.h"
|
#include "fs/devices/Framebuffer.h"
|
||||||
|
#include "bootboot.h"
|
||||||
|
#include "memory/MemoryManager.h"
|
||||||
|
#include "misc/utils.h"
|
||||||
|
#include "std/errno.h"
|
||||||
#include "std/stdio.h"
|
#include "std/stdio.h"
|
||||||
#include "std/stdlib.h"
|
#include "std/stdlib.h"
|
||||||
#include "std/string.h"
|
#include "std/string.h"
|
||||||
#include "memory/MemoryManager.h"
|
|
||||||
#include "utils/Addresses.h"
|
#include "utils/Addresses.h"
|
||||||
#include "misc/utils.h"
|
|
||||||
#include "std/errno.h"
|
|
||||||
#include "bootboot.h"
|
|
||||||
|
|
||||||
extern BOOTBOOT bootboot;
|
extern BOOTBOOT bootboot;
|
||||||
extern char fb[1];
|
extern char fb[1];
|
||||||
@ -36,39 +36,36 @@ uintptr_t FramebufferDevice::mmap(VFS::Node* node, uintptr_t addr, size_t size,
|
|||||||
{
|
{
|
||||||
if (!node) return -1;
|
if (!node) return -1;
|
||||||
int real_prot = prot & ~(MAP_AS_OWNED_BY_TASK);
|
int real_prot = prot & ~(MAP_AS_OWNED_BY_TASK);
|
||||||
if(round_down_to_nearest_page(offset) != (uintptr_t)offset)
|
if (round_down_to_nearest_page(offset) != (uintptr_t)offset) { return MAP_FAIL(EINVAL); }
|
||||||
{
|
if ((size + offset) > bootboot.fb_size)
|
||||||
return MAP_FAIL(EINVAL);
|
|
||||||
}
|
|
||||||
if((size + offset) > bootboot.fb_size)
|
|
||||||
{
|
{
|
||||||
return MAP_FAIL(ERANGE); // FIXME: Should probably be EOVERFLOW.
|
return MAP_FAIL(ERANGE); // FIXME: Should probably be EOVERFLOW.
|
||||||
}
|
}
|
||||||
MemoryManager::map_several_pages(bootboot.fb_ptr + offset, addr, Utilities::get_blocks_from_size(PAGE_SIZE, size), real_prot);
|
MemoryManager::map_several_pages(bootboot.fb_ptr + offset, addr, Utilities::get_blocks_from_size(PAGE_SIZE, size),
|
||||||
|
real_prot);
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t FramebufferDevice::write(VFS::Node* node, size_t offset, size_t size, const char* buffer)
|
ssize_t FramebufferDevice::write(VFS::Node* node, size_t offset, size_t size, const char* buffer)
|
||||||
{
|
{
|
||||||
if (!node) return -1;
|
if (!node) return -1;
|
||||||
if((size + offset) > (uint64_t)bootboot.fb_size)
|
if ((size + offset) > (uint64_t)bootboot.fb_size) { size = (uint64_t)bootboot.fb_size - offset; }
|
||||||
{
|
|
||||||
size = (uint64_t)bootboot.fb_size - offset;
|
|
||||||
}
|
|
||||||
memcpy(fb + offset, buffer, size);
|
memcpy(fb + offset, buffer, size);
|
||||||
return (ssize_t)size;
|
return (ssize_t)size;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define FB_GET_WIDTH 0
|
#define FB_GET_WIDTH 0
|
||||||
#define FB_GET_HEIGHT 1
|
#define FB_GET_HEIGHT 1
|
||||||
|
#define FB_GET_SCANLINE 2
|
||||||
|
|
||||||
long FramebufferDevice::ioctl(VFS::Node* node, int cmd, uintptr_t)
|
long FramebufferDevice::ioctl(VFS::Node* node, int cmd, uintptr_t)
|
||||||
{
|
{
|
||||||
if (!node) return -1;
|
if (!node) return -1;
|
||||||
switch(cmd)
|
switch (cmd)
|
||||||
{
|
{
|
||||||
case FB_GET_WIDTH: return (long)bootboot.fb_width;
|
case FB_GET_WIDTH: return (long)bootboot.fb_width;
|
||||||
case FB_GET_HEIGHT: return (long)bootboot.fb_height;
|
case FB_GET_HEIGHT: return (long)bootboot.fb_height;
|
||||||
|
case FB_GET_SCANLINE: return (long)bootboot.fb_scanline;
|
||||||
default: return -EINVAL;
|
default: return -EINVAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -25,6 +25,16 @@ static const char* format_permissions(uint32_t flags)
|
|||||||
return perms;
|
return perms;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool can_execute_segment(int flags)
|
||||||
|
{
|
||||||
|
return flags & 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool can_write_segment(int flags)
|
||||||
|
{
|
||||||
|
return flags & 2;
|
||||||
|
}
|
||||||
|
|
||||||
ELFImage* ELFLoader::load_elf_from_filesystem(const char* filename)
|
ELFImage* ELFLoader::load_elf_from_filesystem(const char* filename)
|
||||||
{
|
{
|
||||||
VFS::Node* node = VFS::resolve_path(filename);
|
VFS::Node* node = VFS::resolve_path(filename);
|
||||||
@ -90,6 +100,8 @@ ELFImage* ELFLoader::load_elf_from_vfs(VFS::Node* node)
|
|||||||
phdr.p_filesz, phdr.p_memsz, format_permissions(phdr.p_flags));
|
phdr.p_filesz, phdr.p_memsz, format_permissions(phdr.p_flags));
|
||||||
ensure(phdr.p_vaddr);
|
ensure(phdr.p_vaddr);
|
||||||
|
|
||||||
|
ensure(!(can_write_segment(phdr.p_flags) && can_execute_segment(phdr.p_flags)));
|
||||||
|
|
||||||
uint64_t pages = Utilities::get_blocks_from_size(PAGE_SIZE, (phdr.p_vaddr % PAGE_SIZE) + phdr.p_memsz);
|
uint64_t pages = Utilities::get_blocks_from_size(PAGE_SIZE, (phdr.p_vaddr % PAGE_SIZE) + phdr.p_memsz);
|
||||||
void* buffer = (void*)((uint64_t)MemoryManager::get_pages_at(round_down_to_nearest_page(phdr.p_vaddr),
|
void* buffer = (void*)((uint64_t)MemoryManager::get_pages_at(round_down_to_nearest_page(phdr.p_vaddr),
|
||||||
pages, MAP_READ_WRITE) +
|
pages, MAP_READ_WRITE) +
|
||||||
@ -106,8 +118,8 @@ ELFImage* ELFLoader::load_elf_from_vfs(VFS::Node* node)
|
|||||||
VMM::switch_to_previous_user_address_space();
|
VMM::switch_to_previous_user_address_space();
|
||||||
|
|
||||||
int new_flags = MAP_USER | MAP_AS_OWNED_BY_TASK;
|
int new_flags = MAP_USER | MAP_AS_OWNED_BY_TASK;
|
||||||
if(phdr.p_flags & 2) new_flags |= MAP_READ_WRITE;
|
if (can_write_segment(phdr.p_flags)) new_flags |= MAP_READ_WRITE;
|
||||||
if(phdr.p_flags & 1) new_flags |= MAP_EXEC;
|
else if (can_execute_segment(phdr.p_flags)) new_flags |= MAP_EXEC;
|
||||||
|
|
||||||
MemoryManager::protect(buffer, pages, new_flags);
|
MemoryManager::protect(buffer, pages, new_flags);
|
||||||
|
|
||||||
@ -181,6 +193,11 @@ long ELFLoader::check_elf_image(VFS::Node* node)
|
|||||||
kerrorln("trying to load ELF into kernel memory");
|
kerrorln("trying to load ELF into kernel memory");
|
||||||
return -ENOEXEC;
|
return -ENOEXEC;
|
||||||
}
|
}
|
||||||
|
if (can_write_segment(phdr.p_flags) && can_execute_segment(phdr.p_flags))
|
||||||
|
{
|
||||||
|
kwarnln("executable violates W^X");
|
||||||
|
return -ENOEXEC;
|
||||||
|
}
|
||||||
loadable_sections++;
|
loadable_sections++;
|
||||||
memusage += Utilities::get_blocks_from_size(PAGE_SIZE, phdr.p_memsz) * PAGE_SIZE;
|
memusage += Utilities::get_blocks_from_size(PAGE_SIZE, phdr.p_memsz) * PAGE_SIZE;
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
#define FB_GET_WIDTH 0
|
#define FB_GET_WIDTH 0
|
||||||
/* Get the height of a framebuffer device. */
|
/* Get the height of a framebuffer device. */
|
||||||
#define FB_GET_HEIGHT 1
|
#define FB_GET_HEIGHT 1
|
||||||
|
/* Get the scanline of a framebuffer device. */
|
||||||
|
#define FB_GET_SCANLINE 2
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C"
|
extern "C"
|
||||||
|
Loading…
Reference in New Issue
Block a user