Functions for copying stuff between kernel and user space
This commit is contained in:
parent
ace36fe919
commit
19d58ec71d
@ -29,9 +29,8 @@ void kmain(uint64_t multiboot_magic, void *multiboot_data)
|
||||
cpu_init();
|
||||
|
||||
struct process *p1 = new_process((void (*)(void))0x10000);
|
||||
uint64_t page = pmm_alloc();
|
||||
vmm_set_page(p1->P4, 0x10000, page, PAGE_WRITE | PAGE_PRESENT | PAGE_USER);
|
||||
memcpy(P2V(page), (void *)(uintptr_t)thread_function, PAGE_SIZE);
|
||||
vmm_set_page(p1->P4, 0x10000, pmm_calloc(), PAGE_WRITE | PAGE_PRESENT | PAGE_USER);
|
||||
memcpy_k2u(p1->P4, (void *)0x10000, (void *)(uintptr_t)thread_function, 100);
|
||||
|
||||
ready(p1);
|
||||
|
||||
|
@ -45,6 +45,8 @@ uint64_t vmm_get_page(uint64_t P4, uint64_t addr);
|
||||
#define PAGE_EXIST(p) ((p) != (uint64_t)-1)
|
||||
int vmm_set_page(uint64_t P4, uint64_t addr, uint64_t page, uint16_t flags);
|
||||
void vmm_clear_page(uint64_t P4, uint64_t addr, int free);
|
||||
size_t memcpy_k2u(uint64_t P4, void *dst, void *src, size_t n);
|
||||
size_t memcpy_u2k(void *dst, uint64_t P4, void *src, size_t n);
|
||||
|
||||
extern union PTE BootP4;
|
||||
extern int kernel_start, kernel_end;
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include <memory.h>
|
||||
#include <debug.h>
|
||||
|
||||
#define FLAGS_MASK (PAGE_SIZE-1)
|
||||
#define MASK_FLAGS(addr) ((uint64_t)addr & ~FLAGS_MASK)
|
||||
@ -101,3 +102,48 @@ void vmm_clear_page(uint64_t P4, uint64_t addr, int free)
|
||||
pmm_free(MASK_FLAGS(P4E));
|
||||
P4E = 0;
|
||||
}
|
||||
|
||||
#define min(a,b) (((a) < (b))?(a):(b))
|
||||
#define offset(p) ((uintptr_t)(p) % PAGE_SIZE)
|
||||
#define remaining(p) (PAGE_SIZE - offset(p))
|
||||
size_t memcpy_k2u(uint64_t P4, void *dst, void *src, size_t n)
|
||||
{
|
||||
size_t copied = 0;
|
||||
while(n)
|
||||
{
|
||||
size_t bytes = min(remaining(dst), n);
|
||||
uintptr_t page = vmm_get_page(P4, (uintptr_t)dst);
|
||||
if(!PAGE_EXIST(page))
|
||||
return copied;
|
||||
|
||||
void *to = P2V(MASK_FLAGS(page) + offset(dst));
|
||||
memcpy(to, src, bytes);
|
||||
|
||||
copied += bytes;
|
||||
n -= bytes;
|
||||
dst = incptr(dst, bytes);
|
||||
src = incptr(src, bytes);
|
||||
}
|
||||
return copied;
|
||||
}
|
||||
|
||||
size_t memcpy_u2k(void *dst, uint64_t P4, void *src, size_t n)
|
||||
{
|
||||
size_t copied = 0;
|
||||
while(n)
|
||||
{
|
||||
size_t bytes = min(remaining(src), n);
|
||||
uintptr_t page = vmm_get_page(P4, (uintptr_t)src);
|
||||
if(!PAGE_EXIST(page))
|
||||
return copied;
|
||||
|
||||
void *from = P2V(MASK_FLAGS(page) + offset(src));
|
||||
memcpy(dst, from, bytes);
|
||||
|
||||
copied += bytes;
|
||||
n -= bytes;
|
||||
dst = incptr(dst, bytes);
|
||||
src = incptr(src, bytes);
|
||||
}
|
||||
return copied;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user