lab1_练习6

kern/trap/trapentry.S 

 

lab1_练习6_第1张图片

 lab1_练习6_第2张图片

0x7b80 - esp 在tf入栈完毕后入栈

trapframe tf 

0x7b84 - 0x00000000 - edi

0x7b88 - 0x000100b4 - esi

0x7b8c - 0x00007bc8 - ebp

0x7b90 - 0x00007ba4 - oesp    

note: pusha 能入栈%esp,popa不能出栈oesp时不影响%esp,因此%esp只被切换了两次,一次切换至临时frame,使用临时frame中的内容修改选择子的权限,后切换回tf

 

0x7b94 - 0x000100b4 - ebx

0x7b98 - 0x000000a1 - edx

0x7b9c - 0x00000000 - ecx

0x7ba0 - 0x000000ff - eax

-------以上为pusha(pushal)入栈的内容-------

0x7ba4 - 0x00000023 - gs

0x7ba8 - 0x00000023 - fs

0x7bac - 0x00000010 - es

0x7ba0 - 0x00000010 - ds

 

0x7bb4 - trapno

0x7bb8 - err

0x7bbc - ip

0x7bc0 - cs

 

0x7bc4 - eflags

0x7bc8 - esp

0x7bcc - ss   系统调用发生前使用内核代码段作为堆栈 发生后切换为内核数据段

lab1_练习6_第3张图片

lab1_练习6_第4张图片

        case T_SWITCH_TOU:
        if (tf->tf_cs != USER_CS) {
            switchk2u = *tf;
            switchk2u.tf_cs = USER_CS;
            switchk2u.tf_ds = switchk2u.tf_es = switchk2u.tf_ss = USER_DS;

            //和ss一起用于栈的切换的esp 
            //iret发生时由临时的switchk2u切换回tf(系统调用使用的内核栈,但ss的权限被修改)
            switchk2u.tf_esp = (uint32_t)tf + sizeof(struct trapframe) - 8;

            // set eflags, make sure ucore can use io under user mode.
            // if CPL > IOPL, then cpu will generate a general protection.
            switchk2u.tf_eflags |= FL_IOPL_MASK;

            // set temporary stack
            // then iret will jump to the right stack

            // 修改在tf入栈之后入栈的esp 当返回至trapentry时将堆栈切换到临时的switchk2u
            *((uint32_t *)tf - 1) = (uint32_t)&switchk2u;   
        }
        break;

 

 

 

你可能感兴趣的:(ucore)