diff --git a/Makefile b/Makefile index 2fdd31b..8b55f70 100644 --- a/Makefile +++ b/Makefile @@ -182,6 +182,7 @@ UPROGS=\ _usertests\ _wc\ _zombie\ + _test_alloc fs.img: mkfs README $(UPROGS) ./mkfs fs.img README $(UPROGS) diff --git a/syscall.c b/syscall.c index ee85261..58e2eca 100644 --- a/syscall.c +++ b/syscall.c @@ -104,6 +104,9 @@ extern int sys_wait(void); extern int sys_write(void); extern int sys_uptime(void); +extern int sys_alloc_page(void); +extern int sys_free_page(void); + static int (*syscalls[])(void) = { [SYS_fork] sys_fork, [SYS_exit] sys_exit, @@ -126,6 +129,8 @@ static int (*syscalls[])(void) = { [SYS_link] sys_link, [SYS_mkdir] sys_mkdir, [SYS_close] sys_close, +[SYS_alloc_page] sys_alloc_page, +[SYS_free_page] sys_free_page, }; void diff --git a/syscall.h b/syscall.h index 33d0377..62bf907 100644 --- a/syscall.h +++ b/syscall.h @@ -22,3 +22,6 @@ #define SYS_link 19 #define SYS_mkdir 20 #define SYS_close 21 + +#define SYS_alloc_page 22 +#define SYS_free_page 23 diff --git a/test_alloc.c b/test_alloc.c new file mode 100644 index 0000000..6c614bf --- /dev/null +++ b/test_alloc.c @@ -0,0 +1,25 @@ +#include "types.h" +#include "user.h" + +int main(int argc, char**argv) { + + void* base_addr = (void*)0x10000000; + void* addr = base_addr; + for(int i=0; i<10; i++) { + printf(1, "Alloc_page(%p)\n", addr); + alloc_page(addr); + int* ptr = (int*)addr; + *ptr = 1; + + addr += 10000; + } + + addr = base_addr; + for(int i=0; i<10; i++) { + free_page(addr); + addr += 10000; + } + + exit(); + return 0; +} diff --git a/user.h b/user.h index e48c7f7..c3265f8 100644 --- a/user.h +++ b/user.h @@ -26,6 +26,9 @@ char* sbrk(int); int sleep(int); int uptime(void); +int alloc_page(void* addr); +int free_page(void* addr); + // ulib.c int stat(const char*, struct stat*); char* strcpy(char*, const char*); diff --git a/usys.S b/usys.S index 8bfd8a1..b6a749e 100644 --- a/usys.S +++ b/usys.S @@ -29,3 +29,7 @@ SYSCALL(getpid) SYSCALL(sbrk) SYSCALL(sleep) SYSCALL(uptime) + +SYSCALL(alloc_page) +SYSCALL(free_page) + diff --git a/vm.c b/vm.c index 7134cff..397ce46 100644 --- a/vm.c +++ b/vm.c @@ -392,3 +392,45 @@ copyout(pde_t *pgdir, uint va, void *p, uint len) //PAGEBREAK! // Blank page. + + +int sys_alloc_page(void) { + void* addr; + if(argint(0, (int*) &addr) < 0) + return -1; + + addr = (void*)PGROUNDDOWN((int)addr); + cprintf("alloc(%p)\n", addr); + void* kaddr = kalloc(); + if( kaddr == 0) return -1; + memset(kaddr, 0, PGSIZE); + mappages(myproc()->pgdir, addr, PGSIZE, V2P(kaddr), PTE_W|PTE_U); + + return 0; +} + +char* unmappage(pde_t *pgdir, const void* vaddr) { + pte_t* pte = walkpgdir(myproc()->pgdir, (char*)vaddr, 0); + + if(!pte || !(*pte & PTE_P)) + panic("unmapped page"); + + char* res = P2V(PTE_ADDR(*pte)); + + *pte = 0; + + return res; +} + +int sys_free_page(void) { + void* addr; + if(argint(0, (int*) &addr) < 0) + return -1; + + addr = (void*)PGROUNDDOWN((int)addr); + + cprintf("free(%p)\n", addr); + unmappage(myproc()->pgdir, addr); + + return 0; +}