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();
|
cpu_init();
|
||||||
|
|
||||||
struct process *p1 = new_process((void (*)(void))0x10000);
|
struct process *p1 = new_process((void (*)(void))0x10000);
|
||||||
uint64_t page = pmm_alloc();
|
vmm_set_page(p1->P4, 0x10000, pmm_calloc(), PAGE_WRITE | PAGE_PRESENT | PAGE_USER);
|
||||||
vmm_set_page(p1->P4, 0x10000, page, PAGE_WRITE | PAGE_PRESENT | PAGE_USER);
|
memcpy_k2u(p1->P4, (void *)0x10000, (void *)(uintptr_t)thread_function, 100);
|
||||||
memcpy(P2V(page), (void *)(uintptr_t)thread_function, PAGE_SIZE);
|
|
||||||
|
|
||||||
ready(p1);
|
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)
|
#define PAGE_EXIST(p) ((p) != (uint64_t)-1)
|
||||||
int vmm_set_page(uint64_t P4, uint64_t addr, uint64_t page, uint16_t flags);
|
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);
|
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 union PTE BootP4;
|
||||||
extern int kernel_start, kernel_end;
|
extern int kernel_start, kernel_end;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
#define FLAGS_MASK (PAGE_SIZE-1)
|
#define FLAGS_MASK (PAGE_SIZE-1)
|
||||||
#define MASK_FLAGS(addr) ((uint64_t)addr & ~FLAGS_MASK)
|
#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));
|
pmm_free(MASK_FLAGS(P4E));
|
||||||
P4E = 0;
|
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