mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-11-02 07:28:21 +00:00
file mapping stub
This commit is contained in:
@@ -237,6 +237,23 @@ int vfs_open(vnode_t** buff, dirnode_t* ref, char* path){
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int vfs_map(vnode_t* node, void* addr, size_t len, size_t offset, size_t mmuflags){
|
||||||
|
|
||||||
|
spinlock_acquire(&lock);
|
||||||
|
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if(GETTYPE(node->st.st_mode) == TYPE_CHARDEV){
|
||||||
|
err = devman_map(node->st.st_rdev, addr, len, offset, mmuflags);
|
||||||
|
}
|
||||||
|
else _panic("Normal file mapping not supported!", 0);
|
||||||
|
|
||||||
|
spinlock_release(&lock);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
int vfs_create(dirnode_t* ref, char* path, mode_t mode){
|
int vfs_create(dirnode_t* ref, char* path, mode_t mode){
|
||||||
|
|
||||||
dirnode_t* parent = NULL;
|
dirnode_t* parent = NULL;
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ typedef struct{
|
|||||||
int (*isseekable)(int minor, size_t* seekmax);
|
int (*isseekable)(int minor, size_t* seekmax);
|
||||||
int (*ioctl)(int minor, unsigned long request, void* arg, int* result);
|
int (*ioctl)(int minor, unsigned long request, void* arg, int* result);
|
||||||
int (*poll)(int minor, pollfd* fd);
|
int (*poll)(int minor, pollfd* fd);
|
||||||
|
int (*map)(int minor, void* addr, size_t len, size_t offset, size_t mmuflags);
|
||||||
} devcalls;
|
} devcalls;
|
||||||
|
|
||||||
int devman_read(int *error, int dev, void* buff, size_t count, size_t offset);
|
int devman_read(int *error, int dev, void* buff, size_t count, size_t offset);
|
||||||
@@ -27,6 +28,7 @@ int devman_isatty(int dev);
|
|||||||
int devman_isseekable(int dev, size_t* seekmax);
|
int devman_isseekable(int dev, size_t* seekmax);
|
||||||
int devman_ioctl(int dev, unsigned long request, void* arg, int* result);
|
int devman_ioctl(int dev, unsigned long request, void* arg, int* result);
|
||||||
int devman_poll(int dev, pollfd* fd);
|
int devman_poll(int dev, pollfd* fd);
|
||||||
|
int devman_map(int dev, void* addr, size_t len, size_t offset, size_t mmuflags);
|
||||||
void devman_init();
|
void devman_init();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -90,6 +90,7 @@ int vfs_poll(vnode_t* node, pollfd* fd);
|
|||||||
int vfs_chmod(vnode_t* node, mode_t mode);
|
int vfs_chmod(vnode_t* node, mode_t mode);
|
||||||
int vfs_symlink(dirnode_t* ref, char* path, char* target, mode_t mode);
|
int vfs_symlink(dirnode_t* ref, char* path, char* target, mode_t mode);
|
||||||
int vfs_link(dirnode_t* ref, vnode_t* link, char* path);
|
int vfs_link(dirnode_t* ref, vnode_t* link, char* path);
|
||||||
|
int vfs_map(vnode_t* node, void* addr, size_t len, size_t offset, size_t mmuflags);
|
||||||
|
|
||||||
void vfs_init();
|
void vfs_init();
|
||||||
dirnode_t* vfs_root();
|
dirnode_t* vfs_root();
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#ifndef _VMM_H_INCLUDE
|
#ifndef _VMM_H_INCLUDE
|
||||||
#define _VMM_H_INCLUDE
|
#define _VMM_H_INCLUDE
|
||||||
|
|
||||||
|
#include <kernel/vfs.h>
|
||||||
#include <arch/mmu.h>
|
#include <arch/mmu.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
@@ -64,6 +65,7 @@ void* vmm_alloc(size_t pagec, size_t mmuflags);
|
|||||||
bool vmm_setfree(void* addr, size_t pagec);
|
bool vmm_setfree(void* addr, size_t pagec);
|
||||||
bool vmm_allocnowat(void* addr, size_t mmuflags, size_t size);
|
bool vmm_allocnowat(void* addr, size_t mmuflags, size_t size);
|
||||||
void* vmm_allocfrom(void* addr, size_t mmuflags, size_t size);
|
void* vmm_allocfrom(void* addr, size_t mmuflags, size_t size);
|
||||||
|
int vmm_mapfile(vnode_t* node, void* addr, size_t len, size_t offset, size_t mmuflags);
|
||||||
vmm_context* vmm_newcontext();
|
vmm_context* vmm_newcontext();
|
||||||
void vmm_switchcontext(vmm_context*);
|
void vmm_switchcontext(vmm_context*);
|
||||||
int vmm_fork(vmm_context* oldctx, vmm_context* newctx);
|
int vmm_fork(vmm_context* oldctx, vmm_context* newctx);
|
||||||
|
|||||||
@@ -85,6 +85,18 @@ int devman_poll(int dev, pollfd* fd){
|
|||||||
return majorcalls[major(dev)]->poll(minor(dev), fd);
|
return majorcalls[major(dev)]->poll(minor(dev), fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int devman_map(int dev, void* addr, size_t len, size_t offset, size_t mmuflags){
|
||||||
|
|
||||||
|
if(major(dev) > highestmajor)
|
||||||
|
return ENOTTY;
|
||||||
|
|
||||||
|
if(!majorcalls[major(dev)]->map)
|
||||||
|
return ENOTTY;
|
||||||
|
|
||||||
|
return majorcalls[major(dev)]->map(minor(dev), addr, len, offset, mmuflags);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void devman_init(){
|
void devman_init(){
|
||||||
|
|
||||||
devfs_init();
|
devfs_init();
|
||||||
|
|||||||
@@ -551,6 +551,30 @@ bool vmm_setfree(void* addr, size_t pagec){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int vmm_mapfile(vnode_t* node, void* addr, size_t len, size_t offset, size_t mmuflags){
|
||||||
|
|
||||||
|
int* lock;
|
||||||
|
vmm_mapping** start;
|
||||||
|
|
||||||
|
getcontextinfo(addr, &lock, &start);
|
||||||
|
|
||||||
|
spinlock_acquire(lock);
|
||||||
|
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
if(!setmap(start, addr, len, mmuflags, VMM_TYPE_FILE, node, offset))
|
||||||
|
err = ENOMEM;
|
||||||
|
|
||||||
|
if(err == 0)
|
||||||
|
err = vfs_map(node, addr, len, offset, mmuflags);
|
||||||
|
|
||||||
|
spinlock_release(lock);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
bool vmm_map(void* paddr, void* vaddr, size_t pagec, size_t mmuflags){
|
bool vmm_map(void* paddr, void* vaddr, size_t pagec, size_t mmuflags){
|
||||||
int* lock;
|
int* lock;
|
||||||
vmm_mapping** start;
|
vmm_mapping** start;
|
||||||
|
|||||||
+35
-7
@@ -2,6 +2,7 @@
|
|||||||
#include <kernel/vmm.h>
|
#include <kernel/vmm.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <arch/cls.h>
|
||||||
|
|
||||||
// linux abi
|
// linux abi
|
||||||
|
|
||||||
@@ -44,7 +45,7 @@
|
|||||||
#define MFD_CLOEXEC 1U
|
#define MFD_CLOEXEC 1U
|
||||||
#define MFD_ALLOW_SEALING 2U
|
#define MFD_ALLOW_SEALING 2U
|
||||||
|
|
||||||
syscallret syscall_mmap(void* hint, size_t len, int prot, int flags, int fd, off_t offset){
|
syscallret syscall_mmap(void* hint, size_t len, int prot, int flags, int ifd, off_t offset){
|
||||||
|
|
||||||
syscallret retv;
|
syscallret retv;
|
||||||
|
|
||||||
@@ -56,12 +57,6 @@ syscallret syscall_mmap(void* hint, size_t len, int prot, int flags, int fd, off
|
|||||||
return retv;
|
return retv;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((flags & (MAP_ANON | MAP_PRIVATE)) != (MAP_ANON | MAP_PRIVATE)){
|
|
||||||
retv.errno = ENOSYS;
|
|
||||||
return retv;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t mmuflags = 0;
|
size_t mmuflags = 0;
|
||||||
|
|
||||||
if(prot & PROT_READ)
|
if(prot & PROT_READ)
|
||||||
@@ -79,6 +74,8 @@ syscallret syscall_mmap(void* hint, size_t len, int prot, int flags, int fd, off
|
|||||||
|
|
||||||
void* ret = NULL;
|
void* ret = NULL;
|
||||||
|
|
||||||
|
if(flags & MAP_ANON){
|
||||||
|
|
||||||
if(hint)
|
if(hint)
|
||||||
ret = vmm_allocnowat(hint, mmuflags, len) ? hint : NULL; // TODO demand page
|
ret = vmm_allocnowat(hint, mmuflags, len) ? hint : NULL; // TODO demand page
|
||||||
if(ret == NULL && (flags & MAP_FIXED) == 0)
|
if(ret == NULL && (flags & MAP_FIXED) == 0)
|
||||||
@@ -91,6 +88,37 @@ syscallret syscall_mmap(void* hint, size_t len, int prot, int flags, int fd, off
|
|||||||
if(hint && (flags & MAP_ANON))
|
if(hint && (flags & MAP_ANON))
|
||||||
memset(ret, 0, plen*PAGE_SIZE);
|
memset(ret, 0, plen*PAGE_SIZE);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
|
||||||
|
// open node
|
||||||
|
|
||||||
|
proc_t* proc = arch_getcls()->thread->proc;
|
||||||
|
|
||||||
|
fd_t* fd;
|
||||||
|
|
||||||
|
retv.errno = fd_access(&proc->fdtable, &fd, ifd);
|
||||||
|
|
||||||
|
if(retv.errno)
|
||||||
|
return retv;
|
||||||
|
|
||||||
|
|
||||||
|
if(hint)
|
||||||
|
_panic("mmap: file hint unimplemented", 0);
|
||||||
|
|
||||||
|
ret = vmm_allocfrom(USER_ALLOC_START, mmuflags, plen);
|
||||||
|
|
||||||
|
if(!ret)
|
||||||
|
retv.errno = ENOMEM;
|
||||||
|
else{
|
||||||
|
retv.errno = vmm_mapfile(fd->node, ret, plen, offset, mmuflags);
|
||||||
|
if(!retv.errno)
|
||||||
|
retv.ret = ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
fd_release(fd);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return retv;
|
return retv;
|
||||||
|
|
||||||
|
|||||||
+29
-1
@@ -2,6 +2,8 @@
|
|||||||
#include <limine.h>
|
#include <limine.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <arch/mmu.h>
|
||||||
|
#include <arch/cls.h>
|
||||||
|
|
||||||
static volatile struct limine_framebuffer_request fbreq = {
|
static volatile struct limine_framebuffer_request fbreq = {
|
||||||
.id = LIMINE_FRAMEBUFFER_REQUEST,
|
.id = LIMINE_FRAMEBUFFER_REQUEST,
|
||||||
@@ -71,6 +73,7 @@ static int isseekable(int minor, size_t* max){
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define FBIOGET_VSCREENINFO 0x4600
|
#define FBIOGET_VSCREENINFO 0x4600
|
||||||
|
#define FBIOPUT_VSCREENINFO 0x4601
|
||||||
#define FBIOGET_FSCREENINFO 0x4602
|
#define FBIOGET_FSCREENINFO 0x4602
|
||||||
|
|
||||||
struct fb_bitfield {
|
struct fb_bitfield {
|
||||||
@@ -140,6 +143,8 @@ static int ioctl(int minor, unsigned long req, void* arg){
|
|||||||
|
|
||||||
struct limine_framebuffer* fb = fbs[minor];
|
struct limine_framebuffer* fb = fbs[minor];
|
||||||
switch(req){
|
switch(req){
|
||||||
|
case FBIOPUT_VSCREENINFO: // TODO maybe this should be done properly
|
||||||
|
break;
|
||||||
case FBIOGET_FSCREENINFO:
|
case FBIOGET_FSCREENINFO:
|
||||||
{
|
{
|
||||||
fb_fix_screeninfo* i = arg;
|
fb_fix_screeninfo* i = arg;
|
||||||
@@ -205,11 +210,34 @@ static int ioctl(int minor, unsigned long req, void* arg){
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static map(int minor, void* addr, size_t len, size_t offset, size_t mmuflags){
|
||||||
|
|
||||||
|
int properlen = len*PAGE_SIZE;
|
||||||
|
|
||||||
|
int err = devchecks(minor, &properlen, offset);
|
||||||
|
|
||||||
|
properlen /= PAGE_SIZE;
|
||||||
|
|
||||||
|
if(properlen % PAGE_SIZE)
|
||||||
|
++properlen;
|
||||||
|
|
||||||
|
if(err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
for(uintmax_t page = 0; page < len; ++page){
|
||||||
|
if(page < properlen)
|
||||||
|
arch_mmu_map(arch_getcls()->context->context, fbs[minor]->address + offset, addr, mmuflags);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static devcalls calls = {
|
static devcalls calls = {
|
||||||
read, write, isatty, isseekable, ioctl
|
read, write, isatty, isseekable, ioctl, NULL, map
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void fb_init(){
|
void fb_init(){
|
||||||
|
|
||||||
if(!fbreq.response)
|
if(!fbreq.response)
|
||||||
|
|||||||
Reference in New Issue
Block a user