文章目录
Boot xv6
shell
// Execute cmd. Never returns.
void
runcmd(struct cmd *cmd)
{
int p[2], r;
struct execcmd *ecmd;
struct pipecmd *pcmd;
struct redircmd *rcmd;
if(cmd == 0)
_exit(0);
switch(cmd->type){
default:
fprintf(stderr, "unknown runcmd\n");
_exit(-1);
case ' ':
ecmd = (struct execcmd*)cmd;
if(ecmd->argv[0] == 0)
_exit(0);
// fprintf(stderr, "exec not implemented\n");
// Your code here ...
if(!access(ecmd->argv[0], F_OK)) //cmd exists in current directory or not
execv(ecmd->argv[0], ecmd->argv);
else{
char *path = (char*) malloc(150*sizeof(char));
char *root = "/bin/";
strcpy(path, root);
strcat(path, ecmd->argv[0]); //cmd exists in /bin or not
if(!access(path, F_OK))
execv(path, ecmd->argv);
else
fprintf(stderr, "%s: Command not found.n", ecmd->argv[0]);
}
break;
case '>':
case '<':
rcmd = (struct redircmd*)cmd;
// fprintf(stderr, "redir not implemented\n");
// Your code here ...
close(rcmd->fd);
if(open(rcmd->file, rcmd->flags, 0777) < 0){
fprintf(stderr, "open %s failed\n", rcmd->file);
_exit(0);
}
runcmd(rcmd->cmd);
break;
case '|':
pcmd = (struct pipecmd*)cmd;
// fprintf(stderr, "pipe not implemented\n");
// Your code here ...
if(pipe(p) < 0)
_exit(0);
if(fork1() == 0){
close(1);
dup(p[1]);
close(p[0]);
close(p[1]);
runcmd(pcmd->left);
}
if(fork1() == 0){
close(0);
dup(p[0]);
close(p[0]);
close(p[1]);
runcmd(pcmd->right);
}
close(p[0]);
close(p[1]);
wait(&r);
wait(&r);
break;
}
_exit(0);
xv6 system calls
xv6 lazy page allocation
trap.c
需要调用vm.c
中的mappages()
函数,所以需要去除static关键字
在trap.c
中用extern
声明mappages
函数
在trap.c
中的void trap(struct trapframe *tf)
的添加以下代码
//PAGEBREAK: 13
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");
}
// In user space, assume process misbehaved.
char *mem;
uint a;
a = PGROUNDDOWN(rcr2());
uint newsz = myproc()->sz;
for (; a < newsz; a += PGSIZE){
mem = kalloc();
memset(mem, 0, PGSIZE);
mappages(myproc()->pgdir, (char*)a, PGSIZE, V2P(mem), PTE_W|PTE_U);
}
break;
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;
}
xv6 CPU alarm
修改了很多文件,核心是trap.c
的改动,如下:
if(myproc() != 0 && (tf->cs & 3) == 3){
myproc()->totalticks++;
if(myproc()->totalticks == myproc()->alarmticks){
myproc()->totalticks = 0;
tf->esp -= 4;
* (uint*)(tf->esp) = tf->eip;
tf->eip = (uint)myproc()->alarmhandler;
}
}
Threads and Locking
xv6 locking
- 连续两个
acquire
,将会造成panic - 有时会panic,原因是关闭中断后,如果在启动过程中发生了中断,中断处理程序会申请一个锁,但是这个锁已经被kernel持有,导致陷入死锁
- 启动过程中不会panic,因为
filealloc()
在alloc的时候,时间很短,所以很难发生死锁 - 假如先清理掉
lk->locked
,那么lock
就没了,新的进程可能就会在lk->pcs[0]
和lk->cpu
被清零之前获得lock
,但是此时的lk->cpu
和lk->pcs[0]
还是之前的那个,就会导致不一致。