您的位置:首页 > 运维架构 > Linux

linux 0.11 源码学习(七)

2013-05-04 13:37 274 查看
trap.c & Asm.s

trap.c和Asm.s主要完成的是系统中断和陷阱的初始化定义。

注:在80386体系的CPU中中断描述符表替代了中断向量表,IDT的描述符可以是中断门、陷阱门或者任务门。IDT中的中断门和陷阱门的定义如下:BYTE0/1(偏移底字节),BYTE2/3(选择子)、BYTE4/5(属性)、BYTE6/7 (偏移高字节)。通过两个字节的段描述符合四个字节的偏移就可以找到相应的目标代码地址。

因此在看trap.c和Asm.s的代码前,首先要分析下一部分system.h中的代码,如下:

#define _set_gate(gate_addr,type,dpl,addr) \
__asm__ ("movw %%dx,%%ax\n\t" \ //下面四行汇编就是完成IDT描述符的填充
"movw %0,%%dx\n\t" \
"movl %%eax,%1\n\t" \
"movl %%edx,%2" \
: \ //无输出
: "i" ((short) (0x8000+(dpl<<13)+(type<<8))), \//%0参数为IDT的BYTE4,5
"o" (*((char *) (gate_addr))), \//%1变量为内存gate_addr,即门描述符的低四字节
"o" (*(4+(char *) (gate_addr))), \ //%2变量为内存gate_addr+4
"d" ((char *) (addr)),"a" (0x00080000))//edx = addr, eax = 0x00080000; 0x0008为选择字,即对应GDT中的第二个描述符,代码段

#define set_intr_gate(n,addr) \ //n为中断索引
_set_gate(&idt
,14,0,addr) // 14 0x0e属于中断门,DPL设置为0不允许用户态直接访问

#define set_trap_gate(n,addr) \
_set_gate(&idt
,15,0,addr) // 15 0x0f属于属于陷阱门,DPL设置为0不允许用户态直接访问

#define set_system_gate(n,addr) \
_set_gate(&idt
,15,3,addr) //调用门,DPL为3允许用户态访问


在trap.c和Asm.s中具体设置陷阱比较类似,以除零出错为例:

在trap.c的init函数中 set_trap_gate(0, ÷_error)。divider_error函数定义在Asm.s中如下:

divide_error:
pushl $do_divide_error //do_divide_error陷阱处理函数入栈


do_divide_error定义在trap.c中,如下:

void do_divide_error(long esp, long error_code)
{
die("divide error",esp,error_code);//打印当前出错进程的信息
}


其他代码类似,诸如int 3中断或堆栈段错误。

int3:
pushl $do_int3
jmp no_error_code

stack_segment:
pushl $do_stack_segment
jmp error_code


注:这里要值得注意的是do_XX函数的调用,是通过在no_error_code或者error_code中利用iret和堆栈实现的。其中no_error_code要比error_code少入栈一个参数error_code,即我们看到的do_divide_error中的第二个参数。如下:

error_code:
xchgl %eax,4(%esp)       # error code <-> %eax
xchgl %ebx,(%esp)        # &function <-> %ebx
pushl %ecx
pushl %edx
pushl %edi
pushl %esi
pushl %ebp
push %ds
push %es
push %fs
pushl %eax            # error code
lea 44(%esp),%eax     # offset //地址esp+44 赋值给eax,44是堆栈中寄存器长度和,参考赵博的书
pushl %eax
movl $0x10,%eax
mov %ax,%ds
mov %ax,%es
mov %ax,%fs
call *%ebx //调用具体的函数,C语言的入参是放在堆栈里的;
addl $8,%esp //跳过error code和function这8字节
pop %fs
pop %es
pop %ds
popl %ebp
popl %esi
popl %edi
popl %edx
popl %ecx
popl %ebx
popl %eax
iret
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: