os实验lab2
OS操作系统lab2实验报告
1. 当执行完 system_interrupt
函数,执行 153
行 iret
时,记录栈的变化情况。
执行前:
切换后:
system_interrupt函数是内核函数,通过iret返回到用户态,iret来进行栈切换的过程:
iret等价于:
1 | pop ip |
2. 当进入和退出 system_interrupt
时,都发生了模式切换,请总结模式切换时,特权级是如何改变的?栈切换吗?如何进行切换的?
进入system_interrupt的时候,会改变cs和ss分别为0x8、0x10,这个切换是由硬件切换的,cs、ss这两个选择子是由操作系统启动的时候事先设定好的。此时栈有东西被压栈了,压栈的顺序为:
1 | EIP <- ESP |
这里通过压栈报错了cs和ss,返回的时候可以通过iret来进行还原。
退出system_interrupt的时候,通过iret返回,iret会将栈内的数据pop出来恢复寄存器:
1 | pop ip |
总结进入的时候通过硬件自动切换特权级,而退出的时候则通过栈来进行特权级的切换。
细节:
进入是从用户态进入到内核态,通过int80中断进入了,推出是从内核态进入到用户态,通过iret返回。
遇到int80,先将东西压栈,之后返回(看看压了什么
下一条指令地址为0x10eb
让我们看看栈里都压了什么
观察新栈,改变的是esp,eip,cs,ss
1 | EIP <- ESP |
3. 当进入和退出 system_interrupt
时,都发生了模式切换,请总结模式切换时,特权级是如何改变的?栈切换吗?如何进行切换的?
当时钟中断发生,进入到 timer_interrupt
程序,请详细记录从任务 0
切换到任务 1
的过程。
调试方法:
1 | 断点打在0x12b(不知道为何0x12a断不下来 |
timer_interrupt是内核函数
所以会先让DS指向内核数据段
然后设置允许其他硬件中断
然后判断当前任务(框框处为比较
jmpf功效为跳转到别的任务,会进行任务的切换。
jmpf会自动地进行旧任务TSS的保存,以及切换到新任务的TSS,并从新任务的TSS中加载上下文到寄存器。
进行任务跳转的时候会把寄存器等值存到TSS中:
返回时进入到:
4. 又过了 10ms
,从任务1切换回到任务 0
,整个流程是怎样的? TSS
是如何变化的?各个寄存器的值是如何变化的?
10ms之后,硬件再次发送中断,程序将执行到timer_interrupt函数中。
执行完timer_interrupt的一系列汇编之后,同样来到jmpf汇编中。
跳转的时候会保存旧的TSS,并且用要新任务的tss来恢复寄存器。
旧TSS
tr:0x30
新TSS
tr:0x20
跳转到新任务的时候,各个寄存器的值会和新任务的TSS里面的数值一致,确认跳转到新任务。
5. 请详细总结任务切换的过程。
任务切换关键在于:上下文保存、新任务的选择、上下文的恢复(新任务的上下文)、执行新任务。
其中TSS在整个过程中起到了重要的作用,任务切换的时候,先将当前的上下文保存到当前任务的TSS中,然后根据要跳转的新任务选择好TSS选择子,然后进行上下文恢复,如此,就实现了当前的寄存器/堆栈完全是新任务的环境,之后即可执行新任务,新任务执行完毕之后会返回(当然本实验是死循环打印字符不会返回,而是通过中断来进行任务切换回来),任务返回的时候和切换是类似的,同样是TSS的保存以及上下文恢复,通过TSS即可完成上下文的保存和任务的切换!
附:
调试方法:通过打断点的方式即可完成调试
timer_interrupt断点要打在0x12b,任务跳转之后不是跳转到任务的代码而是0x163处的代码是正常的,因为任务跳转返回的是被中断的时候的下一条指令的地址,而任务被打断就是在timer_interrupt的jmpf指令处被打断的,此时EIP被保存为下一条指令地址。