0%

os实验lab2

os实验lab2

OS操作系统lab2实验报告

1. 当执行完 system_interrupt 函数,执行 153 行 iret 时,记录栈的变化情况。

执行前:

Untitled

Untitled

切换后:

Untitled

Untitled

system_interrupt函数是内核函数,通过iret返回到用户态,iret来进行栈切换的过程:

iret等价于:

1
2
3
4
5
pop ip
pop cs
pop eflags
pop esp
pop ss

2. 当进入和退出 system_interrupt 时,都发生了模式切换,请总结模式切换时,特权级是如何改变的?栈切换吗?如何进行切换的?

进入system_interrupt的时候,会改变cs和ss分别为0x8、0x10,这个切换是由硬件切换的,cs、ss这两个选择子是由操作系统启动的时候事先设定好的。此时栈有东西被压栈了,压栈的顺序为:

1
2
3
4
5
EIP <- ESP
CS
eflags
esp
ss

这里通过压栈报错了cs和ss,返回的时候可以通过iret来进行还原。

退出system_interrupt的时候,通过iret返回,iret会将栈内的数据pop出来恢复寄存器:

1
2
3
4
5
pop ip
pop cs
pop eflags
pop esp
pop ss

总结进入的时候通过硬件自动切换特权级,而退出的时候则通过栈来进行特权级的切换。

细节:

进入是从用户态进入到内核态,通过int80中断进入了,推出是从内核态进入到用户态,通过iret返回。

遇到int80,先将东西压栈,之后返回(看看压了什么

Untitled

下一条指令地址为0x10eb

让我们看看栈里都压了什么

观察新栈,改变的是esp,eip,cs,ss

1
2
3
4
5
6
7
8
9
10
11
12
EIP <- ESP
CS
eflags
esp
ss

同时和ret返回的东西刚好对应上
pop ip
pop cs
pop eflags
pop esp
pop ss

3. 当进入和退出 system_interrupt 时,都发生了模式切换,请总结模式切换时,特权级是如何改变的?栈切换吗?如何进行切换的?

当时钟中断发生,进入到 timer_interrupt 程序,请详细记录从任务 0 切换到任务 1 的过程。

调试方法:

1
断点打在0x12b(不知道为何0x12a断不下来

timer_interrupt是内核函数

所以会先让DS指向内核数据段

Untitled

然后设置允许其他硬件中断

Untitled

然后判断当前任务(框框处为比较

Untitled

jmpf功效为跳转到别的任务,会进行任务的切换。

jmpf会自动地进行旧任务TSS的保存,以及切换到新任务的TSS,并从新任务的TSS中加载上下文到寄存器。

进行任务跳转的时候会把寄存器等值存到TSS中:

Untitled

Untitled

返回时进入到:

Untitled

4. 又过了 10ms ,从任务1切换回到任务 0 ,整个流程是怎样的? TSS 是如何变化的?各个寄存器的值是如何变化的?

10ms之后,硬件再次发送中断,程序将执行到timer_interrupt函数中。

执行完timer_interrupt的一系列汇编之后,同样来到jmpf汇编中。

Untitled

跳转的时候会保存旧的TSS,并且用要新任务的tss来恢复寄存器。

旧TSS

tr:0x30

Untitled

Untitled

新TSS

tr:0x20

Untitled

Untitled

跳转到新任务的时候,各个寄存器的值会和新任务的TSS里面的数值一致,确认跳转到新任务。

5. 请详细总结任务切换的过程。

任务切换关键在于:上下文保存、新任务的选择、上下文的恢复(新任务的上下文)、执行新任务。

Untitled

其中TSS在整个过程中起到了重要的作用,任务切换的时候,先将当前的上下文保存到当前任务的TSS中,然后根据要跳转的新任务选择好TSS选择子,然后进行上下文恢复,如此,就实现了当前的寄存器/堆栈完全是新任务的环境,之后即可执行新任务,新任务执行完毕之后会返回(当然本实验是死循环打印字符不会返回,而是通过中断来进行任务切换回来),任务返回的时候和切换是类似的,同样是TSS的保存以及上下文恢复,通过TSS即可完成上下文的保存和任务的切换!

附:

调试方法:通过打断点的方式即可完成调试

timer_interrupt断点要打在0x12b,任务跳转之后不是跳转到任务的代码而是0x163处的代码是正常的,因为任务跳转返回的是被中断的时候的下一条指令的地址,而任务被打断就是在timer_interrupt的jmpf指令处被打断的,此时EIP被保存为下一条指令地址。