文章目录
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]还是之前的那个,就会导致不一致。
本文深入探讨了xv6操作系统的实现细节,包括shell命令执行流程、系统调用机制、懒惰页分配策略、CPU定时警报处理以及线程与锁的管理等内容。


被折叠的 条评论
为什么被折叠?



