|
目前查到的int0x80和sysenter两种系统调用的处理流程:
在执行INT指令时,实际完成了以下几条操作:
1.由于INT指令发生了不同优先级之间的控制转移,所以首先从TSS(任务状态段)中获取高优先级的核心堆栈信息(SS和ESP);
2.把低优先级堆栈信息(SS和ESP)保留到高优先级堆栈(即核心栈)中;
3.把EFLAGS,外层CS,EIP推入高优先级堆栈(核心栈)中。
4.通过IDT加载CS,EIP(控制转移至中断处理函数)
在 Ring3 的代码调用了 sysenter 指令之后,CPU 会做出如下的操作:
1.将 SYSENTER_CS_MSR 的值装载到 cs 寄存器
2.将 SYSENTER_EIP_MSR 的值装载到 eip 寄存器
3.将 SYSENTER_CS_MSR 的值加 8(Ring0 的堆栈段描述符)装载到 ss 寄存器。
4.将 SYSENTER_ESP_MSR 的值装载到 esp 寄存器
5.将特权级切换到 Ring0
6.如果 EFLAGS 寄存器的 VM 标志被置位,则清除该标志
7.开始执行指定的 Ring0 代码
有几个问题:
1.int80调用(4)的中断处理函数直接用struct pt_regs regs作参数就可以访问内核栈?初始化regs的工作谁做的?
2.sysenter时低优先级的EIP和ESP什么时候压入内核栈的?在(7)的处理函数之前如何访问压入栈的低优先级EIP和ESP等等? |
|