lab 2 (probably working)
This commit is contained in:
@@ -110,6 +110,25 @@ syscall(struct trapframe *tf)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
/* Add stuff here */
|
/* Add stuff here */
|
||||||
|
case SYS_read:
|
||||||
|
err = sys_read(
|
||||||
|
(int)tf->tf_a0,
|
||||||
|
(userptr_t)tf->tf_a1,
|
||||||
|
(size_t)tf->tf_a2
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SYS_write:
|
||||||
|
err = sys_write(
|
||||||
|
(int)tf->tf_a0,
|
||||||
|
(userptr_t)tf->tf_a1,
|
||||||
|
(size_t)tf->tf_a2
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SYS__exit:
|
||||||
|
sys__exit((int)tf->tf_a0);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
kprintf("Unknown syscall %d\n", callno);
|
kprintf("Unknown syscall %d\n", callno);
|
||||||
|
|||||||
@@ -55,6 +55,15 @@
|
|||||||
* it's cutting (there are many) and why, and more importantly, how.
|
* it's cutting (there are many) and why, and more importantly, how.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bitmap utils
|
||||||
|
*/
|
||||||
|
#define setBit(A,k) ( A[(k/32)] |= (1 << (k%32)) )
|
||||||
|
#define resetBit(A,k) ( A[(k/32)] &= ~(1 << (k%32)) )
|
||||||
|
#define checkBit(A,k) ( A[(k/32)] & (1 << (k%32)) )
|
||||||
|
|
||||||
|
|
||||||
/* under dumbvm, always have 72k of user stack */
|
/* under dumbvm, always have 72k of user stack */
|
||||||
/* (this must be > 64K so argument blocks of size ARG_MAX will fit) */
|
/* (this must be > 64K so argument blocks of size ARG_MAX will fit) */
|
||||||
#define DUMBVM_STACKPAGES 18
|
#define DUMBVM_STACKPAGES 18
|
||||||
@@ -63,11 +72,35 @@
|
|||||||
* Wrap ram_stealmem in a spinlock.
|
* Wrap ram_stealmem in a spinlock.
|
||||||
*/
|
*/
|
||||||
static struct spinlock stealmem_lock = SPINLOCK_INITIALIZER;
|
static struct spinlock stealmem_lock = SPINLOCK_INITIALIZER;
|
||||||
|
static struct spinlock freemem_lock = SPINLOCK_INITIALIZER;
|
||||||
|
|
||||||
|
static uint32_t *freeRamFrames = NULL;
|
||||||
|
static unsigned long *allocSize = NULL;
|
||||||
|
static int nRamFrames = 0;
|
||||||
|
static int allocTableActive = 0;
|
||||||
|
|
||||||
void
|
void
|
||||||
vm_bootstrap(void)
|
vm_bootstrap(void)
|
||||||
{
|
{
|
||||||
/* Do nothing. */
|
int i;
|
||||||
|
nRamFrames = ((int)ram_getsize())/PAGE_SIZE;
|
||||||
|
/* alloc freeRamFrame and allocSize */
|
||||||
|
freeRamFrames = kmalloc(sizeof(uint32_t)*(nRamFrames/32 + 1));
|
||||||
|
if (freeRamFrames==NULL) return;
|
||||||
|
allocSize = kmalloc(sizeof(unsigned long)*nRamFrames);
|
||||||
|
if (allocSize==NULL) {
|
||||||
|
/* reset to disable this vm management */
|
||||||
|
freeRamFrames = NULL; return;
|
||||||
|
}
|
||||||
|
for (i=0; i<nRamFrames; i++) {
|
||||||
|
if (i<(nRamFrames/32 + 1)) {
|
||||||
|
freeRamFrames[i] = (uint32_t)0;
|
||||||
|
}
|
||||||
|
allocSize[i] = 0;
|
||||||
|
}
|
||||||
|
spinlock_acquire(&freemem_lock);
|
||||||
|
allocTableActive = 1;
|
||||||
|
spinlock_release(&freemem_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -90,17 +123,88 @@ dumbvm_can_sleep(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static paddr_t
|
||||||
paddr_t
|
getfreeppages(unsigned long npages) {
|
||||||
|
paddr_t addr;
|
||||||
|
long i, first, found, np = (long)npages;
|
||||||
|
|
||||||
|
spinlock_acquire(&freemem_lock);
|
||||||
|
if (!allocTableActive) {
|
||||||
|
spinlock_release(&freemem_lock);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
for (i=0,first=found=-1; i<nRamFrames; i++) {
|
||||||
|
if (checkBit(freeRamFrames, i)) {
|
||||||
|
if (i==0 || !checkBit(freeRamFrames, i-1))
|
||||||
|
first = i; /* set first free in an interval */
|
||||||
|
if (i-first+1 >= np) {
|
||||||
|
found = first;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found>=0) {
|
||||||
|
for (i=found; i<found+np; i++) {
|
||||||
|
resetBit(freeRamFrames, i);
|
||||||
|
}
|
||||||
|
allocSize[found] = np;
|
||||||
|
addr = (paddr_t) found*PAGE_SIZE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
addr = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
spinlock_release(&freemem_lock);
|
||||||
|
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
freeppages(paddr_t addr, unsigned long npages){
|
||||||
|
long i, first, np=(long)npages;
|
||||||
|
|
||||||
|
spinlock_acquire(&freemem_lock);
|
||||||
|
if (!allocTableActive) {
|
||||||
|
spinlock_release(&freemem_lock);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
first = addr/PAGE_SIZE;
|
||||||
|
KASSERT(allocSize!=NULL);
|
||||||
|
KASSERT(nRamFrames>first);
|
||||||
|
|
||||||
|
for (i=first; i<first+np; i++) {
|
||||||
|
setBit(freeRamFrames, i);
|
||||||
|
}
|
||||||
|
spinlock_release(&freemem_lock);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static paddr_t
|
||||||
getppages(unsigned long npages)
|
getppages(unsigned long npages)
|
||||||
{
|
{
|
||||||
paddr_t addr;
|
paddr_t addr;
|
||||||
|
|
||||||
spinlock_acquire(&stealmem_lock);
|
/* try freed pages first */
|
||||||
|
addr = getfreeppages(npages);
|
||||||
|
if (addr == 0) {
|
||||||
|
/* call stealmem */
|
||||||
|
spinlock_acquire(&stealmem_lock);
|
||||||
|
addr = ram_stealmem(npages);
|
||||||
|
spinlock_release(&stealmem_lock);
|
||||||
|
}
|
||||||
|
if (addr!=0) {
|
||||||
|
spinlock_acquire(&freemem_lock);
|
||||||
|
if (!allocTableActive) {
|
||||||
|
spinlock_release(&freemem_lock);
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
allocSize[addr/PAGE_SIZE] = npages;
|
||||||
|
spinlock_release(&freemem_lock);
|
||||||
|
}
|
||||||
|
|
||||||
addr = ram_stealmem(npages);
|
|
||||||
|
|
||||||
spinlock_release(&stealmem_lock);
|
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,9 +225,17 @@ alloc_kpages(unsigned npages)
|
|||||||
void
|
void
|
||||||
free_kpages(vaddr_t addr)
|
free_kpages(vaddr_t addr)
|
||||||
{
|
{
|
||||||
/* nothing - leak the memory. */
|
spinlock_acquire(&freemem_lock);
|
||||||
|
if (!allocTableActive) {
|
||||||
(void)addr;
|
spinlock_release(&freemem_lock);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
spinlock_release(&freemem_lock);
|
||||||
|
paddr_t paddr = addr - MIPS_KSEG0;
|
||||||
|
long first = paddr/PAGE_SIZE;
|
||||||
|
KASSERT(allocSize!=NULL);
|
||||||
|
KASSERT(nRamFrames>first);
|
||||||
|
freeppages(paddr, allocSize[first]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
@@ -440,6 +440,10 @@ file test/fstest.c
|
|||||||
optfile net test/nettest.c
|
optfile net test/nettest.c
|
||||||
|
|
||||||
|
|
||||||
# NEW PDS WORK
|
# NEW PDS WORK (lab1)
|
||||||
defoption hello
|
defoption hello
|
||||||
optfile hello main/hello.c
|
optfile hello main/hello.c
|
||||||
|
|
||||||
|
# LAB2
|
||||||
|
file syscall/file_syscalls.c
|
||||||
|
file syscall/proc_syscalls.c
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
#ifndef _SYSCALL_H_
|
#ifndef _SYSCALL_H_
|
||||||
#define _SYSCALL_H_
|
#define _SYSCALL_H_
|
||||||
|
|
||||||
|
#include <types.h>
|
||||||
#include <cdefs.h> /* for __DEAD */
|
#include <cdefs.h> /* for __DEAD */
|
||||||
struct trapframe; /* from <machine/trapframe.h> */
|
struct trapframe; /* from <machine/trapframe.h> */
|
||||||
|
|
||||||
@@ -59,4 +59,9 @@ __DEAD void enter_new_process(int argc, userptr_t argv, userptr_t env,
|
|||||||
int sys_reboot(int code);
|
int sys_reboot(int code);
|
||||||
int sys___time(userptr_t user_seconds, userptr_t user_nanoseconds);
|
int sys___time(userptr_t user_seconds, userptr_t user_nanoseconds);
|
||||||
|
|
||||||
|
size_t sys_read(int filehandle, userptr_t buf, size_t size);
|
||||||
|
size_t sys_write(int filehandle, const userptr_t buf, size_t size);
|
||||||
|
|
||||||
|
void sys__exit(int status);
|
||||||
|
|
||||||
#endif /* _SYSCALL_H_ */
|
#endif /* _SYSCALL_H_ */
|
||||||
|
|||||||
32
kern/syscall/file_syscalls.c
Normal file
32
kern/syscall/file_syscalls.c
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
#include <syscall.h>
|
||||||
|
#include <lib.h>
|
||||||
|
#include <kern/unistd.h>
|
||||||
|
|
||||||
|
size_t sys_read(int fh, userptr_t buf, size_t size) {
|
||||||
|
int i=0;
|
||||||
|
int * ary = (int*)buf;
|
||||||
|
if (fh!=STDIN_FILENO) {
|
||||||
|
kprintf("sys_read supported only to stdin\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0;i<(int)size;i++) {
|
||||||
|
ary[i] = getch();
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t sys_write(int fh, const userptr_t buf, size_t size) {
|
||||||
|
int i=0;
|
||||||
|
int * ary = (int*)buf;
|
||||||
|
|
||||||
|
if (fh!=STDOUT_FILENO && fh!=STDERR_FILENO) {
|
||||||
|
kprintf("sys_write supported only to stdout\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0;i<(int)size;i++) {
|
||||||
|
putch(ary[i]);
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
15
kern/syscall/proc_syscalls.c
Normal file
15
kern/syscall/proc_syscalls.c
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
#include <syscall.h>
|
||||||
|
#include <proc.h>
|
||||||
|
#include <thread.h>
|
||||||
|
#include <addrspace.h>
|
||||||
|
|
||||||
|
void sys__exit(int status) {
|
||||||
|
(void)status;
|
||||||
|
/* delete current process as */
|
||||||
|
struct addrspace *as = proc_getas();
|
||||||
|
as_destroy(as);
|
||||||
|
/* exit thread */
|
||||||
|
thread_exit();
|
||||||
|
|
||||||
|
panic("sys__exit end reached!!\n");
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user