init commit of lab2_2

lab2_2_allocatepage
Zhiyuan Shao 3 years ago
parent 769c280d05
commit 032708bd84

@ -70,7 +70,7 @@ USER_OBJS := $(addprefix $(OBJ_DIR)/, $(patsubst %.c,%.o,$(USER_CPPS)))
USER_TARGET := $(OBJ_DIR)/app_helloworld_no_lds
USER_TARGET := $(OBJ_DIR)/app_naive_malloc
#------------------------targets------------------------
$(OBJ_DIR):
@-mkdir -p $(OBJ_DIR)

@ -1,5 +1,6 @@
#ifndef _MEMLAYOUT_H
#define _MEMLAYOUT_H
#include "riscv.h"
// RISC-V machine places its physical memory above DRAM_BASE
#define DRAM_BASE 0x80000000
@ -13,4 +14,7 @@
// virtual address of stack top of user process
#define USER_STACK_TOP 0x7ffff000
// start virtual address (4MB) of our simple heap. added @lab2_2
#define USER_FREE_ADDRESS_START 0x00000000 + PGSIZE * 1024
#endif

@ -24,6 +24,9 @@ extern void return_to_user(trapframe *, uint64 satp);
// current points to the currently running user-mode application.
process* current = NULL;
// points to the first free page in our simple heap. added @lab2_2
uint64 g_ufree_page = USER_FREE_ADDRESS_START;
//
// switch to a user-mode process
//

@ -34,4 +34,7 @@ void switch_to(process*);
// current running process
extern process* current;
// address of the first free page in our simple heap. added @lab2_2
extern uint64 g_ufree_page;
#endif

@ -36,6 +36,27 @@ ssize_t sys_user_exit(uint64 code) {
shutdown(code);
}
//
// maybe, the simplest implementation of malloc in the world ... added @lab2_2
//
uint64 sys_user_allocate_page() {
void* pa = alloc_page();
uint64 va = g_ufree_page;
g_ufree_page += PGSIZE;
user_vm_map((pagetable_t)current->pagetable, va, PGSIZE, (uint64)pa,
prot_to_type(PROT_WRITE | PROT_READ, 1));
return va;
}
//
// reclaim a page, indicated by "va". added @lab2_2
//
uint64 sys_user_free_page(uint64 va) {
user_vm_unmap((pagetable_t)current->pagetable, va, PGSIZE, 1);
return 0;
}
//
// [a0]: the syscall number; [a1] ... [a7]: arguments to the syscalls.
// returns the code of success, (e.g., 0 means success, fail for otherwise)
@ -46,6 +67,11 @@ long do_syscall(long a0, long a1, long a2, long a3, long a4, long a5, long a6, l
return sys_user_print((const char*)a1, a2);
case SYS_user_exit:
return sys_user_exit(a1);
// added @lab2_2
case SYS_user_allocate_page:
return sys_user_allocate_page();
case SYS_user_free_page:
return sys_user_free_page(a1);
default:
panic("Unknown syscall %ld \n", a0);
}

@ -8,6 +8,9 @@
#define SYS_user_base 64
#define SYS_user_print (SYS_user_base + 0)
#define SYS_user_exit (SYS_user_base + 1)
// added @lab2_2
#define SYS_user_allocate_page (SYS_user_base + 2)
#define SYS_user_free_page (SYS_user_base + 3)
long do_syscall(long a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7);

@ -171,3 +171,19 @@ void user_vm_map(pagetable_t page_dir, uint64 va, uint64 size, uint64 pa, int pe
panic("fail to user_vm_map .\n");
}
}
//
// unmap virtual address [va, va+size] from the user app.
// reclaim the physical pages if free!=0
//
void user_vm_unmap(pagetable_t page_dir, uint64 va, uint64 size, int free) {
// TODO (lab2_2): implement user_vm_unmap to disable the mapping of the virtual pages
// in [va, va+size], and free the corresponding physical pages used by the virtual
// addresses when if 'free' (the last parameter) is not zero.
// basic idea here is to first locate the PTEs of the virtual pages, and then reclaim
// (use free_page() defined in pmm.c) the physical pages. lastly, invalidate the PTEs.
// as naive_free reclaims only one page at a time, you only need to consider one page
// to make user/app_naive_malloc to behave correctly.
panic( "You have to implement user_vm_unmap to free pages using naive_free in lab2_2.\n" );
}

@ -29,5 +29,6 @@ void kern_vm_init(void);
/* --- user page table --- */
void *user_va_to_pa(pagetable_t page_dir, void *va);
void user_vm_map(pagetable_t page_dir, uint64 va, uint64 size, uint64 pa, int perm);
void user_vm_unmap(pagetable_t page_dir, uint64 va, uint64 size, int free);
#endif

@ -1,12 +0,0 @@
/*
* Below is the given application for lab2_1.
* This app runs in its own address space, in contrast with in direct mapping.
*/
#include "user_lib.h"
#include "util/types.h"
int main(void) {
printu("Hello world!\n");
exit(0);
}

@ -0,0 +1,22 @@
/*
* Below is the given application for lab2_2.
*/
#include "user_lib.h"
#include "util/types.h"
struct my_structure {
char c;
int n;
};
int main(void) {
struct my_structure* s = (struct my_structure*)naive_malloc();
s->c = 'a';
s->n = 1;
printu("s: %lx, {%c %d}\n", s, s->c, s->n);
naive_free(s);
exit(0);
}

@ -10,7 +10,7 @@
#include "util/snprintf.h"
#include "kernel/syscall.h"
int do_user_call(uint64 sysnum, uint64 a1, uint64 a2, uint64 a3, uint64 a4, uint64 a5, uint64 a6,
uint64 do_user_call(uint64 sysnum, uint64 a1, uint64 a2, uint64 a3, uint64 a4, uint64 a5, uint64 a6,
uint64 a7) {
int ret;
@ -49,3 +49,17 @@ int printu(const char* s, ...) {
int exit(int code) {
return do_user_call(SYS_user_exit, code, 0, 0, 0, 0, 0, 0);
}
//
// lib call to naive_malloc
//
void* naive_malloc() {
return (void*)do_user_call(SYS_user_allocate_page, 0, 0, 0, 0, 0, 0, 0);
}
//
// lib call to naive_free
//
void naive_free(void* va) {
do_user_call(SYS_user_free_page, (uint64)va, 0, 0, 0, 0, 0, 0);
}

@ -4,3 +4,5 @@
int printu(const char *s, ...);
int exit(int code);
void* naive_malloc();
void naive_free(void* va);

Loading…
Cancel
Save