����8-2 linux/kernel/traps.c


  1 /*

  2  *  linux/kernel/traps.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 /*

  8  * 'Traps.c' handles hardware traps and faults after we have saved some

  9  * state in 'asm.s'. Currently mostly a debugging-aid, will be extended

 10  * to mainly kill the offending process (probably by giving it a signal,

 11  * but possibly by killing it outright if necessary).

 12  */

    /*

     * �ڳ���asm.s�б�����һЩ״̬�󣬱�������������Ӳ������͹��ϡ�Ŀǰ��Ҫ���ڵ���Ŀ�ģ�

     * �Ժ���չ����ɱ�����𻵵Ľ��̣���Ҫ��ͨ������һ���źţ��������ҪҲ��ֱ��ɱ������

     */

 13 #include <string.h>       // �ַ���ͷ�ļ�����Ҫ������һЩ�й��ڴ���ַ���������Ƕ�뺯����

 14

 15 #include <linux/head.h>   // headͷ�ļ��������˶��������ļ򵥽ṹ���ͼ���ѡ���������

 16 #include <linux/sched.h>  // ���ȳ���ͷ�ļ�������������ṹtask_struct����ʼ����0�����ݣ�

                              // ����һЩ�й��������������úͻ�ȡ��Ƕ��ʽ��ຯ������䡣

 17 #include <linux/kernel.h> // �ں�ͷ�ļ�������һЩ�ں˳��ú�����ԭ�ζ��塣

 18 #include <asm/system.h>   // ϵͳͷ�ļ������������û��޸�������/�ж��ŵȵ�Ƕ��ʽ���ꡣ

 19 #include <asm/segment.h>  // �β���ͷ�ļ����������йضμĴ���������Ƕ��ʽ��ຯ����

 20 #include <asm/io.h>       // ����/���ͷ�ļ�������Ӳ���˿�����/���������䡣

 21

    // ������䶨��������Ƕ��ʽ������亯�����й�Ƕ��ʽ���Ļ����﷨���������б����˵����

    // ��Բ������ס�������䣨�������е���䣩������Ϊ����ʽʹ�ã���������__res�������ֵ��

    // ��23�ж�����һ���Ĵ�������__res���ñ�������������һ���Ĵ����У��Ա��ڿ��ٷ��ʺͲ�����

    // �����ָ���Ĵ���������eax������ô���ǿ��԰Ѹþ�д�ɡ�register char __res asm("ax");����

    // ȡ��seg�е�ַaddr����һ���ֽڡ�

    // ������seg - ��ѡ�����addr - ����ָ����ַ��

    // �����%0 - eax (__res)�����룺%1 - eax (seg)��%2 - �ڴ��ַ (*(addr))��

 22 #define get_seg_byte(seg,addr) ({ \

 23 register char __res; \

 24 __asm__("push %%fs;mov %%ax,%%fs;movb %%fs:%2,%%al;pop %%fs" \

 25         :"=a" (__res):"0" (seg),"m" (*(addr))); \

 26 __res;})

 27

    // ȡ��seg�е�ַaddr����һ�����֣�4�ֽڣ���

    // ������seg - ��ѡ�����addr - ����ָ����ַ��

    // �����%0 - eax (__res)�����룺%1 - eax (seg)��%2 - �ڴ��ַ (*(addr))��

 28 #define get_seg_long(seg,addr) ({ \

 29 register unsigned long __res; \

 30 __asm__("push %%fs;mov %%ax,%%fs;movl %%fs:%2,%%eax;pop %%fs" \

 31         :"=a" (__res):"0" (seg),"m" (*(addr))); \

 32 __res;})

 33

    // ȡfs�μĴ�����ֵ��ѡ�������

    // �����%0 - eax (__res)��

 34 #define _fs() ({ \

 35 register unsigned short __res; \

 36 __asm__("mov %%fs,%%ax":"=a" (__res):); \

 37 __res;})

 38

    // ���¶�����һЩ����ԭ�͡�

 39 void page_exception(void);                   // ҳ�쳣��ʵ����page_fault��mm/page.s��14����

 40

 41 void divide_error(void);                     // int0��kernel/asm.s��20����

 42 void debug(void);                            // int1��kernel/asm.s��54����

 43 void nmi(void);                              // int2��kernel/asm.s��58����

 44 void int3(void);                             // int3��kernel/asm.s��62����

 45 void overflow(void);                         // int4��kernel/asm.s��66����

 46 void bounds(void);                           // int5��kernel/asm.s��70����

 47 void invalid_op(void);                       // int6��kernel/asm.s��74����

 48 void device_not_available(void);             // int7��kernel/sys_call.s��158����

 49 void double_fault(void);                     // int8��kernel/asm.s��98����

 50 void coprocessor_segment_overrun(void);      // int9��kernel/asm.s��78����

 51 void invalid_TSS(void);                      // int10��kernel/asm.s��132����

 52 void segment_not_present(void);              // int11��kernel/asm.s��136����

 53 void stack_segment(void);                    // int12��kernel/asm.s��140����

 54 void general_protection(void);               // int13��kernel/asm.s��144����

 55 void page_fault(void);                       // int14��mm/page.s��14����

 56 void coprocessor_error(void);                // int16��kernel/sys_call.s��140����

 57 void reserved(void);                         // int15��kernel/asm.s��82����

 58 void parallel_interrupt(void);               // int39��kernel/sys_call.s��295����

 59 void irq13(void);                            // int45 Э�������жϴ�����kernel/asm.s��86����

 60 void alignment_check(void);                  // int46��kernel/asm.s��148����

 61

    // ���ӳ���������ӡ�����жϵ����ơ������š����ó����EIP��EFLAGS��ESP��fs�μĴ���ֵ��

    // �εĻ�ַ���εij��ȡ����̺�pid������š�10�ֽ�ָ���롣�����ջ���û����ݶΣ���

    // ��ӡ16�ֽڵĶ�ջ���ݡ���Щ��Ϣ�����ڳ�����ԡ�

 62 static void die(char * str,long esp_ptr,long nr)

 63 {

 64         long * esp = (long *) esp_ptr;

 65         int i;

 66

 67         printk("%s: %04x\n\r",str,nr&0xffff);

    // ���д�ӡ�����ʾ��ǰ���ý��̵�CS:EIP��EFLAGS��SS:ESP��ֵ����������!δ�ҵ�����Դ����֪������esp[0]

    // ��Ϊͼ�е�esp0λ�á�������ǰ�����ֿ�����Ϊ��

    // (1) EIP:\t%04x:%p\n  -- esp[1]�Ƕ�ѡ�����cs����esp[0]��eip

    // (2) EFLAGS:\t%p      -- esp[2]��eflags

    // (3) ESP:\t%04x:%p\n  -- esp[4]��ԭss��esp[3]��ԭesp

 68         printk("EIP:\t%04x:%p\nEFLAGS:\t%p\nESP:\t%04x:%p\n",

 69                 esp[1],esp[0],esp[2],esp[4],esp[3]);

 70         printk("fs: %04x\n",_fs());

 71         printk("base: %p, limit: %p\n",get_base(current->ldt[1]),get_limit(0x17));

 72         if (esp[4] == 0x17) {             // ��ԭssֵΪ0x17���û�ջ�����򻹴�ӡ��

 73                 printk("Stack: ");        // �û�ջ�е�4������ֵ��16�ֽڣ���

 74                 for (i=0;i<4;i++)

 75                         printk("%p ",get_seg_long(0x17,i+(long *)esp[3]));

 76                 printk("\n");

 77         }

 78         str(i);                 // ȡ��ǰ�������������ţ�include/linux/sched.h��210�У���

 79         printk("Pid: %d, process nr: %d\n\r",current->pid,0xffff & i); // ���̺ţ�����š�

 80         for(i=0;i<10;i++)

 81                 printk("%02x ",0xff & get_seg_byte(esp[1],(i+(char *)esp[0])));

 82         printk("\n\r");

 83         do_exit(11);            /* play segment exception */

 84 }

 85

    // ������Щ��do_��ͷ�ĺ�����asm.s�ж�Ӧ�жϴ���������õ�C������

 86 void do_double_fault(long esp, long error_code)

 87 {

 88         die("double fault",esp,error_code);

 89 }

 90

 91 void do_general_protection(long esp, long error_code)

 92 {

 93         die("general protection",esp,error_code);

 94 }

 95

 96 void do_alignment_check(long esp, long error_code)

 97 {

 98     die("alignment check",esp,error_code);

 99 }

100

101 void do_divide_error(long esp, long error_code)

102 {

103         die("divide error",esp,error_code);

104 }

105

    // �����ǽ����жϺ�˳��ѹ���ջ�ļĴ���ֵ���μ�asm.s�����24--35�С�

106 void do_int3(long * esp, long error_code,

107                 long fs,long es,long ds,

108                 long ebp,long esi,long edi,

109                 long edx,long ecx,long ebx,long eax)

110 {

111         int tr;

112

113         __asm__("str %%ax":"=a" (tr):"" (0));               // ȡ����Ĵ���ֵ��tr��

114         printk("eax\t\tebx\t\tecx\t\tedx\n\r%8x\t%8x\t%8x\t%8x\n\r",

115                 eax,ebx,ecx,edx);

116         printk("esi\t\tedi\t\tebp\t\tesp\n\r%8x\t%8x\t%8x\t%8x\n\r",

117                 esi,edi,ebp,(long) esp);

118         printk("\n\rds\tes\tfs\ttr\n\r%4x\t%4x\t%4x\t%4x\n\r",

119                 ds,es,fs,tr);

120         printk("EIP: %8x   CS: %4x  EFLAGS: %8x\n\r",esp[0],esp[1],esp[2]);

121 }

122

123 void do_nmi(long esp, long error_code)

124 {

125         die("nmi",esp,error_code);

126 }

127

128 void do_debug(long esp, long error_code)

129 {

130         die("debug",esp,error_code);

131 }

132

133 void do_overflow(long esp, long error_code)

134 {

135         die("overflow",esp,error_code);

136 }

137

138 void do_bounds(long esp, long error_code)

139 {

140         die("bounds",esp,error_code);

141 }

142

143 void do_invalid_op(long esp, long error_code)

144 {

145         die("invalid operand",esp,error_code);

146 }

147

148 void do_device_not_available(long esp, long error_code)

149 {

150         die("device not available",esp,error_code);

151 }

152

153 void do_coprocessor_segment_overrun(long esp, long error_code)

154 {

155         die("coprocessor segment overrun",esp,error_code);

156 }

157

158 void do_invalid_TSS(long esp,long error_code)

159 {

160         die("invalid TSS",esp,error_code);

161 }

162

163 void do_segment_not_present(long esp,long error_code)

164 {

165         die("segment not present",esp,error_code);

166 }

167

168 void do_stack_segment(long esp,long error_code)

169 {

170         die("stack segment",esp,error_code);

171 }

172

173 void do_coprocessor_error(long esp, long error_code)

174 {

175         if (last_task_used_math != current)

176                 return;

177         die("coprocessor error",esp,error_code);

178 }

179

180 void do_reserved(long esp, long error_code)

181 {

182         die("reserved (15,17-47) error",esp,error_code);

183 }

184

    // �������쳣�����壩�жϳ����ʼ���ӳ����������ǵ��жϵ����ţ��ж���������

    // set_trap_gate()��set_system_gate()��ʹ�����ж���������IDT�е������ţ�Trap Gate����

    // ����֮�����Ҫ��������ǰ�����õ���Ȩ��Ϊ0��������3����˶ϵ������ж�int3������ж�

    // overflow �ͱ߽�����ж� bounds �������κγ�����á� ��������������Ƕ��ʽ�������

    // �μ�include/asm/system.h����36�С�39�С�

185 void trap_init(void)

186 {

187         int i;

188

189         set_trap_gate(0,&divide_error);     // ���ó������������ж�����ֵ��������ͬ��

190         set_trap_gate(1,&debug);

191         set_trap_gate(2,&nmi);

192         set_system_gate(3,&int3);           /* int3-5 can be called from all */

193         set_system_gate(4,&overflow);       /* int3-5 ���Ա����г���ִ�� */

194         set_system_gate(5,&bounds);

195         set_trap_gate(6,&invalid_op);

196         set_trap_gate(7,&device_not_available);

197         set_trap_gate(8,&double_fault);

198         set_trap_gate(9,&coprocessor_segment_overrun);

199         set_trap_gate(10,&invalid_TSS);

200         set_trap_gate(11,&segment_not_present);

201         set_trap_gate(12,&stack_segment);

202         set_trap_gate(13,&general_protection);

203         set_trap_gate(14,&page_fault);

204         set_trap_gate(15,&reserved);

205         set_trap_gate(16,&coprocessor_error);

206         set_trap_gate(17,&alignment_check);

 

    // �����int17-47���������Ⱦ�����Ϊreserved���Ժ��Ӳ����ʼ��ʱ�����������Լ��������š�

207         for (i=18;i<48;i++)

208                 set_trap_gate(i,&reserved);

 

    // ����Э�������ж�0x2d��45����������������������������ж��������ò��п��ж���������

209         set_trap_gate(45,&irq13);

210         outb_p(inb_p(0x21)&0xfb,0x21);          // ����8259A��оƬ��IRQ2�ж�����

211         outb(inb_p(0xA1)&0xdf,0xA1);            // ����8259A��оƬ��IRQ13�ж�����

212         set_trap_gate(39,&parallel_interrupt);  // ���ò��п�1���ж�0x27��������������

213 }

214