0%

调试分析Linux0.00引导程序

调试分析Linux0.00引导程序

简述head.s的工作原理

​ 主要包括初始设置与任务执行切换。

​ 初始设置包括:

1.设置GDT表。

2.设置系统定时芯片。

3.设置IDT表。

4.切换到任务0。

任务执行切换则为:

​ head.s程序中把定时器芯片8253的通道0设置成每经过10ms就向中断控制芯片8259A发送一个时钟中断请求信号。PC机的ROM BIOS开机时已经在8259A把时钟中断请求信号设置成中断向量8,在中断8的处理过程中执行任务切换操作。任务切换的实现方法是查看current变量中当前运行任务号,若当前为0,就利用任务1的TSS选择符作为操作数执行远跳转指令,从而切换到任务1中执行,否则反之。

​ 每个任务在执行时,会先把一个字符的ASCLL码放入寄存器AL中,然后调用系统中断调用int 0x80,而该系统调用处理过程则会调用一个简单的字符写屏子程序,把寄存器AL中的字符显示在屏幕上,同时把字符显示的屏幕下一个位置记录下来,作为下一次显示字符的屏幕位置。在显示过一个字符后,任务代码会使用循环语句延迟一段时间,然后跳转到任务代码开始出继续循环执行,从而不断显示。

记录head.s的内存分布情况

首先从GDT表看起,GDTR为0x998(3f),则跳转到0x998去。寄存器SS的内容为0010。

由于第一项为空,则从第二项看,第二项为FF 07 00 00 00 9A C0 00。将其填写到段描述中,发现其S为1,TYPE为A,为代码段,G为1,段限长为0 07 FF ,基地址为0。则实际段长度为8MB。

第三项为FF 07 00 00 00 93 C0 00。将其填写到段描述中,发现其S为1,TYPE为3,为栈段,G为1,段限长为0 07 FF ,基地址为0,B/D为1。

第四项为02 00 00 80 0B 92 C0 00,将其填写到段描述符中,发现其S为1,TYPE为2,为数据段,G为1,段限长为0 00 02,基地址为0XB8000。则实际段长度为8KB。

第五、第六、七项S为0。

再查询任务0 LDT表

同理分析,则代码段与数据段基地址均为0,段限长为0x03ff,实际长度为4MB。

再查询任务1 LDT表

同理分析,则代码段与数据段基地址均为0,段限长为0x03ff,实际长度为4MB。

再运行到任务0处,此时SS寄存器为0x17,栈段基地址为0,段限长为0x03ff。

运行到任务1同理,此时SS寄存器为0x17,栈段基地址为0,段限长为0x03ff。

初始化的代码段起始地址为0,段长为8MB,则终止地址为0X800000。数据段起始地址为0XB8000,段长为8kb,终止地址为0XBA000。

任务0的代码段起始地址为0,段长为4MB,则终止地址为0X400000。数据段起始地址为0,段长为4MB,则终止地址为0X400000。

任务1的代码段起始地址为0,段长为4MB,则终止地址为0X400000。数据段起始地址为0,段长为4MB,则终止地址为0X400000。

栈段编号 名称 起始地址 终止地址
1 init_stack 0x9d8 0xbd8
2 Km_stk0 0xc60 0xe60
3 Km_stk1 0xe00 0x10e0
4 User _stk1 0x1108 0x1308

简述head.s 57-62行

将新调度任务(任务0)的上下文,加载进处理器中,并将从加载的EIP指向的指令出开始执行。具体操作为

57:将任务0当前局部空间数据段选择符入栈,

58:将堆栈指针入栈,

59:将标志寄存器值入栈,

60:将当前局部空间代码段选择符入栈,

61:将代码指针入栈,

62:通过执行中断返回指令,切换到特权级3的任务0执行。·

简述iret执行后,PC如何找到下一条指令。

image-20220427150129063

在iret执行前,eip的值为000000ac,esp为00000bc4,cs的值为0008,栈顶的值为000010e0,然后执行iret。

image-20220427150336651

栈内五条内容均被弹出,其中000010e0被写入eip,同时0000000f被写入cs,则获得了下一条指令的地址。

记录iret执行前后,栈的变化

执行前

image-20220427151617085

执行后

image-20220427151627637

看上述两张图,图一为执行时,ss为0010,esp为00000bc4,当iret执行后,会弹出五条内容。分别为之前保存的寄存器eip的值,寄存器cs的值,标志寄存器eflags的值,寄存器esp的值,寄存器ss的值。

系统调用int 0x80时,栈的变化情况

调用int 0x80前,栈为task0或task1的用户栈

image-20220427151837544

调用int 0x80后,为此任务的系统栈。

image-20220427152127334

由于执行前任务特权级为3,而执行后任务特权级为0,所以进行了栈切换。压入了中断前的ss、栈指针、标志寄存器、cs和下一条指令的eip。ss寄存器的值也发生了相应变化。