`
spartan1
  • 浏览: 360336 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

ucore-project4: 内核态和用户态切换(2)

 
阅读更多

用户态到内核态切换相对比较简单。用户态切换到内核态时,需要切换堆栈,堆栈地址在当前task的tss段中,因此需要先建立好一个task,并为内核态的ss和esp赋好值。

 

仍然使用中断切换到内核态,中断处理函数中,首先将保存在新堆栈中的老堆栈的esp取出来,然后在老堆栈的esp指针指向位置之上建立一个trapframe(不包括ss和esp值),然后将新堆栈中的这一堆内容拷贝过来,然后给tf赋值为新堆栈的trapframe的地址,之后直接返回到trap_asm就ok了。

 

在使用过程中,发现切换不了。使用gdb跟踪发现,不断发生通用保护异常13,才发现idt中为用户态切换到内核态而建的中断的中断描述符的dpl仍然为0,没有改成3,导致执行该中断时不断发生通用保护异常。将该中断描述符的dpl设置为DPL_USER(3)后,切换正常:

struct trapframe *newtf = (struct trapframe*)(tf->esp - sizeof(struct trapframe) + 8);
memmove(newtf, tf, sizeof(struct trapframe)-8);
// newtf has no ss
// newtf->ss = SS_KDATA;
newtf->cs = SS_KTEXT;
newtf->ds = SS_KDATA;
newtf->es = SS_KDATA;
newtf->fs = SS_KDATA;
newtf->gs = SS_KDATA;

tf = newtf;

 建立中断描述符表的代码改一下:

int i;
for (i=0; i<256; i++)
    setintrgate(&idt[i], SS_KTEXT, vectors[i], DPL_KERNEL);

setintrgate(&idt[TRAPNO_U2K], SS_KTEXT, vectors[TRAPNO_U2K], DPL_USER);

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics