kern/trap/trapentry.S
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 系统调用发生前使用内核代码段作为堆栈 发生后切换为内核数据段
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;