summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kernel.ld7
-rw-r--r--proc.c16
-rw-r--r--trapasm.S11
3 files changed, 22 insertions, 12 deletions
diff --git a/kernel.ld b/kernel.ld
index e78fd38..11dc98f 100644
--- a/kernel.ld
+++ b/kernel.ld
@@ -41,9 +41,10 @@ SECTIONS
.data : {
*(.data)
}
- PROVIDE(edata = .);
- .bss : {
+ bss : {
+ PROVIDE(edata = .);
*(.bss)
+ *(COMMON)
+ PROVIDE(end = .);
}
- PROVIDE(end = .);
}
diff --git a/proc.c b/proc.c
index 58ae948..3ab23f4 100644
--- a/proc.c
+++ b/proc.c
@@ -6,7 +6,6 @@
#include "x86.h"
#include "proc.h"
#include "spinlock.h"
-#include "msr.h"
struct {
struct spinlock lock;
@@ -17,7 +16,11 @@ static struct proc *initproc;
int nextpid = 1;
extern void forkret(void);
+
+// we can return two ways out of the kernel and
+// for new processes we can choose either way
extern void sysexit(void);
+extern void trapret(void);
static void wakeup1(void *chan);
@@ -101,6 +104,10 @@ found:
// Leave room for trap frame.
sp -= sizeof *p->tf;
+
+ if ((uint64) sp % 16)
+ panic("misaligned sp");
+
p->tf = (struct trapframe*)sp;
// Set up new context to start executing at forkret,
@@ -132,6 +139,8 @@ userinit(void)
inituvm(p->pgdir, _binary_initcode_start, (uint64)_binary_initcode_size);
p->sz = PGSIZE;
memset(p->tf, 0, sizeof(*p->tf));
+ p->tf->cs = UCSEG | 0x3;
+ p->tf->ss = UDSEG | 0x3;
p->tf->r11 = FL_IF;
p->tf->rsp = PGSIZE;
p->tf->rcx = 0; // beginning of initcode.S
@@ -321,12 +330,12 @@ scheduler(void)
{
struct proc *p;
struct cpu *c = mycpu();
+
c->proc = 0;
-
for(;;){
// Enable interrupts on this processor.
sti();
-
+
// Loop over process table looking for process to run.
acquire(&ptable.lock);
for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){
@@ -336,7 +345,6 @@ scheduler(void)
// Switch to chosen process. It is the process's job
// to release ptable.lock and then reacquire it
// before jumping back to us.
-
c->proc = p;
switchuvm(p);
p->state = RUNNING;
diff --git a/trapasm.S b/trapasm.S
index b6dbb1a..d160ff2 100644
--- a/trapasm.S
+++ b/trapasm.S
@@ -22,7 +22,7 @@ alltraps:
push %rbx
push %rax
- cmpw $KCSEG, 32(%rsp) # compare to saved cs
+ cmpw $KCSEG, 144(%rsp) # compare to saved cs
jz 1f
swapgs
@@ -33,7 +33,7 @@ alltraps:
.globl trapret
trapret:
cli
- cmpw $KCSEG, 32(%rsp) # compare to saved cs
+ cmpw $KCSEG, 144(%rsp) # compare to saved cs
jz 1f
swapgs
@@ -72,12 +72,12 @@ sysentry: # Build trap frame.
movq %rax, %rsp
movq %gs:0, %rax // restore rax
- // push usp
- push $0
+ // push usp to make a valid trapframe
+ push $(UDSEG|0x3)
push %gs:8
// safe eflags and eip
push %r11
- push $UCSEG
+ push $(UCSEG|0x3)
push %rcx
// push errno and trapno to make stack look like a trap
push $0
@@ -130,6 +130,7 @@ sysexit:
add $(5*8), %rsp # discard trapnum, errorcode, rip, cs and rflags
mov (%rsp),%rsp # switch to the user stack
+ # there are two more values on the stack, but we don't care about them
swapgs
sysretq