Part One: Eliminate allocation from sbrk()
在sysproc.c中找到sys_sbrk(void)函数,注释掉:
/*
if(growproc(n) < 0)
return -1;
*/
即可。
Part Two: Lazy allocation
在trap.c中将default情况改为如下:
default:
if(myproc() == 0 || (tf->cs&3) == 0){
// In kernel, it must be our mistake.
cprintf("unexpected trap %d from cpu %d eip %x (cr2=0x%x)\n",
tf->trapno, cpuid(), tf->eip, rcr2());
panic("trap");
}
//缺页的情况
if (tf->trapno == T_PGFLT)
{
char* pa;
uint addr = PGROUNDDOWN(rcr2());
pa = kalloc();
if (pa == 0)
{
panic("in functio trap:out of memory\n");
return;
}
memset(pa,0,PGSIZE);
if (mappages(myproc()->pgdir,(void*)addr,PGSIZE,V2P(pa),PTE_W|PTE_U)<0)
{
panic("error occurs while mapping:in function trap\n");
return ;
}
break;
}
//缺页情况结束
// In user space, assume process misbehaved.
cprintf("pid %d %s: trap %d err %d on cpu %d "
"eip 0x%x addr 0x%x--kill proc\n",
myproc()->pid, myproc()->name, tf->trapno,
tf->err, cpuid(), tf->eip, rcr2());
myproc()->killed = 1;
}
// Force process exit if it has been killed and is in user space.
// (If it is still executing in the kernel, let it keep running
// until it gets to the regular system call return.)
if(myproc() && myproc()->killed && (tf->cs&3) == DPL_USER)
exit();
// Force process to give up CPU on clock tick.
// If interrupts were on while locks held, would need to check nlock.
if(myproc() && myproc()->state == RUNNING &&
tf->trapno == T_IRQ0+IRQ_TIMER)
yield();
// Check if the process has been killed since we yielded
if(myproc() && myproc()->killed && (tf->cs&3) == DPL_USER)
exit();
大概思想就是:为发生错误的地址处分配一个物理页,并将其进行相应的映射。
Optional challenges
Handle negative sbrk() arguments
在sysproc.c的sys_sbrk(void)里面添加一个判断语句:
if (n < 0)
{
if (growproc(n)<0)
return -1;
}
为负的情况直接释放掉。
Handle error cases such as sbrk() arguments that are too large
判断虚拟地址是否涉及到内核部分:
if (addr+n>KERNBASE)
{
cprintf("ABOVE KERNBASE!\n");
return -1;
}
所以最终的sys_sbrk应该是下面这样:
int
sys_sbrk(void)
{
int addr;
int n;
if(argint(0, &n) < 0)
return -1;
addr = myproc()->sz;
if (n < 0)
{
if (growproc(n)<0)
return -1;
}
if (addr+n>KERNBASE)
{
cprintf("ABOVE KERNBASE!\n");
return -1;
}
/*
if(growproc(n) < 0)
return -1;
*/
myproc()->sz += n;
return addr;
}
后面的略。
END.