提交 0a70d042 创建 作者: rtm's avatar rtm

more or less take traps/interrupts

上级 70a895f6
OBJS = main.o console.o string.o kalloc.o proc.o trapasm.o
OBJS = main.o console.o string.o kalloc.o proc.o trapasm.o trap.o vectors.o
CC = i386-jos-elf-gcc
LD = i386-jos-elf-ld
......@@ -23,5 +23,8 @@ kernel : $(OBJS)
$(LD) -Ttext 0x100000 -e main -o kernel $(OBJS)
$(OBJDUMP) -S kernel > kernel.asm
vectors.S : vectors.pl
perl vectors.pl > vectors.S
clean :
rm -f *.o bootblock kernel kernel.asm xv6.img
......@@ -65,3 +65,11 @@ perhaps have fixed-size stack, put it in the data segment?
oops, if kernel stack is in contiguous user phys mem, then moving
users' memory (e.g. to expand it) will wreck any pointers into the
kernel stack.
do we need to set fs and gs? so user processes can't abuse them?
setupsegs() may modify current segment table, is that legal?
trap() ought to lgdt on return, since currently only done in swtch()
protect hardware interrupt vectors from user INT instructions?
差异被折叠。
......@@ -14,8 +14,8 @@ main()
cprintf("\nxV6\n\n");
// initialize physical memory allocator
kinit();
kinit(); // physical memory allocator
tinit(); // traps and interrupts
// create fake process zero
p = &proc[0];
......@@ -33,6 +33,10 @@ main()
p = newproc(&proc[0]);
// xxx copy instructions to p->mem
p->mem[0] = 0x90; // nop
p->mem[1] = 0x90; // nop
p->mem[2] = 0x42; // inc %edx
p->mem[3] = 0x42; // inc %edx
p->tf->tf_eip = 0;
p->tf->tf_esp = p->sz;
......
......@@ -20,7 +20,8 @@ setupsegs(struct proc *p)
p->ts.ts_ss0 = SEG_KDATA << 3;
p->ts.ts_esp0 = (unsigned)(p->kstack + KSTACKSIZE);
memset(&p->gdt, 0, sizeof(p->gdt));
// XXX it may be wrong to modify the current segment table!
p->gdt[0] = SEG_NULL;
p->gdt[SEG_KCODE] = SEG(STA_X|STA_R, 0, 0xffffffff, 0);
p->gdt[SEG_KDATA] = SEG(STA_W, 0, 0xffffffff, 0);
......@@ -73,7 +74,7 @@ newproc(struct proc *op)
np->esp = (unsigned) sp;
np->ebp = (unsigned) sp;
cprintf("esp %x ebp %x mem %x\n", np->esp, np->ebp, np->mem);
cprintf("newproc esp %x ebp %x mem %x\n", np->esp, np->ebp, np->mem);
return np;
}
......@@ -101,12 +102,18 @@ swtch(struct proc *op)
op->ebp = read_ebp();
op->esp = read_esp();
cprintf("switching\n");
// XXX callee-saved registers?
// XXX probably ought to lgdt on trap return too
asm volatile("lgdt %0" : : "g" (np->gdt_pd.pd_lim));
ltr(SEG_TSS << 3);
// this happens to work, but probably isn't safe:
// it's not clear that np->ebp will evaluate
// it's not clear that np->ebp is guaranteed to evaluate
// correctly after changing the stack pointer.
asm volatile("lgdt %0" : : "g" (np->gdt_pd.pd_lim));
asm volatile("movl %0, %%esp" : : "g" (np->esp));
asm volatile("movl %0, %%ebp" : : "g" (np->ebp));
}
#include "mmu.h"
.text
.globl alltraps
.globl trap
alltraps:
/* vectors.S sends all traps here */
pushl %ds # build
pushl %es # trap
pushal # frame
movl $16,%eax # SEG_KDATA << 3
movw %ax,%ds # kernel
movw %ax,%es # segments
pushl %esp # pass pointer to this trapframe
call trap # and call trap()
# return falls through to trapret...
.globl trapret
/*
* a forked process RETs here
......
#!/usr/bin/perl -w
# generate vectors.S, the trap/interrupt entry points.
# there has to be one entry point per interrupt number
# since otherwise there's no way to tell the interrupt
# number.
print "/* generated by vectors.pl */\n";
print ".text\n";
print ".globl alltraps\n";
for(my $i = 0; $i < 256; $i++){
print ".globl vector$i\n";
print "vector$i:\n";
if(($i < 8 || $i > 14) && $i != 17){
print "\tpushl \$0\n";
}
print "\tpushl $i\n";
print "\tjmp alltraps\n";
}
print ".data\n";
print ".globl vectors\n";
print "vectors:\n";
for(my $i = 0; $i < 256; $i++){
print ".long vector$i\n";
}
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论