冬天OS(六):中断

--------------------------------------------------------

初始化 8259A

--------------------------------------------------------

上一节我们编写了 Makefile ,享受到了 Makefile 带给我们的便利,这节我们乘着 make 的便利来设置中断...

 

一,initial 8259A
8259A 是一种可编程中断控制芯片,我们只有对两片级联的芯片编程之后才可以使用,其中值得注意的是 IRQ0 和 IRQ8 中断向量号的指定,我们后面会基于这两个数值安排 8259A 中断处理函数!还有一个需要注意的是,OCW 控制字可以控制是否允许某个类型的中断,初始化我们默认 disable 所有类型的中断!

上图是就是初始化 8259A 的代码...

 

二,设置 IDT register
为内核设置 IDT 的方法和设置 GDT 的方法是一模一样的,只是当初我们是做了 GTD 的转移到 C 程序中,如今不需要转移,而是直接设置 IDT 的位置在 C 程序中!

 

可以看到设置 IDT register 和 设置 GDT register 完全相同!

 

三,初始化中断向量
中断向量初始化重要的是设置中断入口和注意中断返回!我们只初始化了 0 ~ 15 号中断入口!
 

; ----------------------------
; <kernel>
; Jack Zheng 11.27
; ----------------------------
SELECTOR_KERNEL_CS      equ     8

; global functions!
extern  cstart
extern  exception_handler;
extern  spuripus_irq;

; global variables!
extern  gdt_ptr
extern  idt_ptr
extern  disp_pos

bits 32
[SECTION .bss]
StackSpace      resb    2 * 1024
StackTop:
[section .text]
global  _start

global  divide_error
global  single_step_exception
global  nmi
global  breakpoint_exception
global  overflow
global  bounds_check
global  inval_opcode
global  copr_not_available
global  double_fault
global  copr_seg_overrun
global  inval_tss
global  segment_not_present
global  stack_exception
global  general_protection
global  page_fault
global  copr_error

_start:

        ; reset esp to kernel!
        mov     esp, StackTop
        mov     dword [disp_pos], 0
        sgdt    [gdt_ptr]
        call    cstart
        lgdt    [gdt_ptr]
        lidt    [idt_ptr]

        jmp     SELECTOR_KERNEL_CS:csinit
csinit:
        jmp    0x40:0
        jmp     $

; 中断和异常 -- 异常
divide_error:
        push    0xFFFFFFFF      ; no err code
        push    0               ; vector_no     = 0
        jmp     exception
single_step_exception:
        push    0xFFFFFFFF      ; no err code
        push    1               ; vector_no     = 1
        jmp     exception
nmi:
        push    0xFFFFFFFF      ; no err code
        push    2               ; vector_no     = 2
        jmp     exception
breakpoint_exception:
        push    0xFFFFFFFF      ; no err code
        push    3               ; vector_no     = 3
        jmp     exception
overflow:
        push    0xFFFFFFFF      ; no err code
        push    4               ; vector_no     = 4
        jmp     exception
bounds_check:
        push    0xFFFFFFFF      ; no err code
        push    5               ; vector_no     = 5
        jmp     exception
inval_opcode:
        push    0xFFFFFFFF      ; no err code
        push    6               ; vector_no     = 6
        jmp     exception
copr_not_available:
        push    0xFFFFFFFF      ; no err code
        push    7               ; vector_no     = 7
        jmp     exception
double_fault:
        push    8               ; vector_no     = 8
        jmp     exception
copr_seg_overrun:
        push    0xFFFFFFFF      ; no err code
        push    9               ; vector_no     = 9
        jmp     exception
inval_tss:
        push    10              ; vector_no     = A
        jmp     exception
segment_not_present:
        push    11              ; vector_no     = B
        jmp     exception
stack_exception:
        push    12              ; vector_no     = C
        jmp     exception
general_protection:
        push    13              ; vector_no     = D
        jmp     exception
page_fault:
        push    14              ; vector_no     = E
        jmp     exception
copr_error:
        push    0xFFFFFFFF      ; no err code
        push    16              ; vector_no     = 10h
        jmp     exception

exception:
        call    exception_handler
        add     esp, 4*2        ; 让栈顶指向 EIP,堆栈中从顶向下依次是:EIP、CS、EFLAGS
        hlt

——kernel.asm 中就是各中断的中断入口,可以看到,进入中断入口之后就调用了 exception_handler 来处理对中断的响应!

// ----------------------------
// <protect.c>
// Jack Zheng 11.27
// ----------------------------
#include "type.h"
#include "const.h"
#include "protect.h"
#include "global.h"

/* 本文件内函数声明 */
PRIVATE void init_idt_desc(unsigned char vector, t_8 desc_type, t_pf_int_handler handler, unsigned char privilege);

/* 中断处理函数 */
void    divide_error();
void    single_step_exception();
void    nmi();
void    breakpoint_exception();
void    overflow();
void    bounds_check();
void    inval_opcode();
void    copr_not_available();
void    double_fault();
void    copr_seg_overrun();
void    inval_tss();
void    segment_not_present();
void    stack_exception();
void    general_protection();
void    page_fault();
void    copr_error();
/*
void    hwint00();
void    hwint01();
void    hwint02();
void    hwint03();
void    hwint04();
void    hwint05();
void    hwint06();
void    hwint07();
void    hwint08();
void    hwint09();
void    hwint10();
void    hwint11();
void    hwint12();
void    hwint13();
void    hwint14();
void    hwint15();
*/

PUBLIC void init_idt_desc(unsigned char vector, t_8 desc_type, t_pf_int_handler handler, unsigned char privilege)
{
        GATE *  p_gate  = &idt[vector];
        t_32    base    = (t_32)handler;
        p_gate->offset_low      = base & 0xFFFF;
        p_gate->selector        = SELECTOR_KERNEL_CS;
        p_gate->dcount          = 0;
        p_gate->attr            = desc_type | (privilege << 5);
        p_gate->offset_high     = (base >> 16) & 0xFFFF;
}

PUBLIC void init_prot()
{
        init_8259A();

        // 全部初始化成中断门(没有陷阱门)
        init_idt_desc(INT_VECTOR_DIVIDE,        DA_386IGate, divide_error,              PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_DEBUG,         DA_386IGate, single_step_exception,     PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_NMI,           DA_386IGate, nmi,                       PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_BREAKPOINT,    DA_386IGate, breakpoint_exception,      PRIVILEGE_USER);
        init_idt_desc(INT_VECTOR_OVERFLOW,      DA_386IGate, overflow,                  PRIVILEGE_USER);
        init_idt_desc(INT_VECTOR_BOUNDS,        DA_386IGate, bounds_check,              PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_INVAL_OP,      DA_386IGate, inval_opcode,              PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_COPROC_NOT,    DA_386IGate, copr_not_available,        PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_DOUBLE_FAULT,  DA_386IGate, double_fault,              PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_COPROC_SEG,    DA_386IGate, copr_seg_overrun,          PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_INVAL_TSS,     DA_386IGate, inval_tss,                 PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_SEG_NOT,       DA_386IGate, segment_not_present,       PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_STACK_FAULT,   DA_386IGate, stack_exception,           PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_PROTECTION,    DA_386IGate, general_protection,        PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_PAGE_FAULT,    DA_386IGate, page_fault,                PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_COPROC_ERR,    DA_386IGate, copr_error,                PRIVILEGE_KRNL);
/*
        init_idt_desc(INT_VECTOR_IRQ0 + 0,      DA_386IGate, hwint00,                   PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_IRQ0 + 1,      DA_386IGate, hwint01,                   PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_IRQ0 + 2,      DA_386IGate, hwint02,                   PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_IRQ0 + 3,      DA_386IGate, hwint03,                   PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_IRQ0 + 4,      DA_386IGate, hwint04,                   PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_IRQ0 + 5,      DA_386IGate, hwint05,                   PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_IRQ0 + 6,      DA_386IGate, hwint06,                   PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_IRQ0 + 7,      DA_386IGate, hwint07,                   PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_IRQ8 + 0,      DA_386IGate, hwint08,                   PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_IRQ8 + 1,      DA_386IGate, hwint09,                   PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_IRQ8 + 2,      DA_386IGate, hwint10,                   PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_IRQ8 + 3,      DA_386IGate, hwint11,                   PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_IRQ8 + 4,      DA_386IGate, hwint12,                   PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_IRQ8 + 5,      DA_386IGate, hwint13,                   PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_IRQ8 + 6,      DA_386IGate, hwint14,                   PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_IRQ8 + 7,      DA_386IGate, hwint15,                   PRIVILEGE_KRNL);
*/
}

PUBLIC void exception_handler(int vec_no, int err_code, int eip, int cs, int eflags)
{
        int i;
        int text_color = 0x74; /* 灰底红字 */
        char err_description[][64] = {  "#DE Divide Error",
                                        "#DB RESERVED",
                                        "—  NMI Interrupt",
                                        "#BP Breakpoint",
                                        "#OF Overflow",
                                        "#BR BOUND Range Exceeded",
                                        "#UD Invalid Opcode (Undefined Opcode)",
                                        "#NM Device Not Available (No Math Coprocessor)",
                                        "#DF Double Fault",
                                        "    Coprocessor Segment Overrun (reserved)",
                                        "#TS Invalid TSS",
                                        "#NP Segment Not Present",
                                        "#SS Stack-Segment Fault",
                                        "#GP General Protection",
                                        "#PF Page Fault",
                                        "—  (Intel reserved. Do not use.)",
                                        "#MF x87 FPU Floating-Point Error (Math Fault)",
                                        "#AC Alignment Check",
                                        "#MC Machine Check",
                                        "#XF SIMD Floating-Point Exception"
                                };

        /* 通过打印空格的方式清空屏幕的前五行,并把 disp_pos 清零 */
        disp_pos = 0;
        for(i=0;i<80*5;i++){
                disp_str(" ");
        }
        disp_pos = 0;

        disp_color_str("Exception! --> ", text_color);
        disp_color_str(err_description[vec_no], text_color);
        disp_color_str("\n\n", text_color);
        disp_color_str("EFLAGS:", text_color);
        disp_int(eflags);
        disp_color_str("CS:", text_color);
        disp_int(cs);
        disp_color_str("EIP:", text_color);
        disp_int(eip);

        if(err_code != 0xFFFFFFFF){
                disp_color_str("Error code:", text_color);
                disp_int(err_code);
        }
}

——protect.c 中设置这些中断入口!

 

运行:

可以看到,我们确实触发了异常,并打印出了错误码!

 

四,初始化外部中断
初始化外部中断和前面的初始化异常都是一样的,只是需要注意我们的 IRQ0 和 IRQ8 对应的中断向量号是 20h、28h!
 

; ----------------------------
; <kernel>
; Jack Zheng 11.27
; ----------------------------
SELECTOR_KERNEL_CS      equ     8

; global functions!
extern  cstart
extern  exception_handler;
extern  spurious_irq;

; global variables!
extern  gdt_ptr
extern  idt_ptr
extern  disp_pos

bits 32
[SECTION .bss]
StackSpace      resb    2 * 1024
StackTop:
[section .text]
global  _start

global  divide_error
global  single_step_exception
global  nmi
global  breakpoint_exception
global  overflow
global  bounds_check
global  inval_opcode
global  copr_not_available
global  double_fault
global  copr_seg_overrun
global  inval_tss
global  segment_not_present
global  stack_exception
global  general_protection
global  page_fault
global  copr_error
global  hwint00
global  hwint01
global  hwint02
global  hwint03
global  hwint04
global  hwint05
global  hwint06
global  hwint07
global  hwint08
global  hwint09
global  hwint10
global  hwint11
global  hwint12
global  hwint13
global  hwint14
global  hwint15

_start:

        ; reset esp to kernel!
        mov     esp, StackTop
        mov     dword [disp_pos], 0
        sgdt    [gdt_ptr]
        call    cstart
        lgdt    [gdt_ptr]
        lidt    [idt_ptr]

        jmp     SELECTOR_KERNEL_CS:csinit
csinit:
        ; exception test!
        ; jmp   0x40:0

        ; interrupt test!
        sti
        jmp     $

; 中断和异常 -- 异常
divide_error:
        push    0xFFFFFFFF      ; no err code
        push    0               ; vector_no     = 0
        jmp     exception
single_step_exception:
        push    0xFFFFFFFF      ; no err code
        push    1               ; vector_no     = 1
        jmp     exception
nmi:
        push    0xFFFFFFFF      ; no err code
        push    2               ; vector_no     = 2
        jmp     exception
breakpoint_exception:
        push    0xFFFFFFFF      ; no err code
        push    3               ; vector_no     = 3
        jmp     exception
overflow:
        push    0xFFFFFFFF      ; no err code
        push    4               ; vector_no     = 4
        jmp     exception
bounds_check:
        push    0xFFFFFFFF      ; no err code
        push    5               ; vector_no     = 5
        jmp     exception
inval_opcode:
        push    0xFFFFFFFF      ; no err code
        push    6               ; vector_no     = 6
        jmp     exception
copr_not_available:
        push    0xFFFFFFFF      ; no err code
        push    7               ; vector_no     = 7
        jmp     exception
double_fault:
        push    8               ; vector_no     = 8
        jmp     exception
copr_seg_overrun:
        push    0xFFFFFFFF      ; no err code
        push    9               ; vector_no     = 9
        jmp     exception
inval_tss:
        push    10              ; vector_no     = A
        jmp     exception
segment_not_present:
        push    11              ; vector_no     = B
        jmp     exception
stack_exception:
        push    12              ; vector_no     = C
        jmp     exception
general_protection:
        push    13              ; vector_no     = D
        jmp     exception
page_fault:
        push    14              ; vector_no     = E
        jmp     exception
copr_error:
        push    0xFFFFFFFF      ; no err code
        push    16              ; vector_no     = 10h
        jmp     exception

exception:
        call    exception_handler
        add     esp, 4*2        ; 让栈顶指向 EIP,堆栈中从顶向下依次是:EIP、CS、EFLAGS
        hlt

; 中断和异常 -- 硬件中断
; ---------------------------------
%macro  hwint_master    1
        push    %1
        call    spurious_irq
        add     esp, 4
        hlt
%endmacro


ALIGN   16
hwint00:                ; Interrupt routine for irq 0 (the clock).
        hwint_master    0

ALIGN   16
hwint01:                ; Interrupt routine for irq 1 (keyboard)
        hwint_master    1

ALIGN   16
hwint02:                ; Interrupt routine for irq 2 (cascade!)
        hwint_master    2

ALIGN   16
hwint03:                ; Interrupt routine for irq 3 (second serial)
        hwint_master    3

ALIGN   16
hwint04:                ; Interrupt routine for irq 4 (first serial)
        hwint_master    4

ALIGN   16
hwint05:                ; Interrupt routine for irq 5 (XT winchester)
        hwint_master    5

ALIGN   16
hwint06:                ; Interrupt routine for irq 6 (floppy)
        hwint_master    6

ALIGN   16
hwint07:                ; Interrupt routine for irq 7 (printer)
        hwint_master    7

; ---------------------------------
%macro  hwint_slave     1
        push    %1
        call    spurious_irq
        add     esp, 4
        hlt
%endmacro
; ---------------------------------

ALIGN   16
hwint08:                ; Interrupt routine for irq 8 (realtime clock).
        hwint_slave     8

ALIGN   16
hwint09:                ; Interrupt routine for irq 9 (irq 2 redirected)
        hwint_slave     9

ALIGN   16
hwint10:                ; Interrupt routine for irq 10
        hwint_slave     10

ALIGN   16
hwint11:                ; Interrupt routine for irq 11
        hwint_slave     11

ALIGN   16
hwint12:                ; Interrupt routine for irq 12
        hwint_slave     12

ALIGN   16
hwint13:                ; Interrupt routine for irq 13 (FPU exception)
        hwint_slave     13

ALIGN   16
hwint14:                ; Interrupt routine for irq 14 (AT winchester)
        hwint_slave     14

ALIGN   16
hwint15:                ; Interrupt routine for irq 15
        hwint_slave     15
// ----------------------------
// <protect.c>
// Jack Zheng 11.27
// ----------------------------
#include "type.h"
#include "const.h"
#include "protect.h"
#include "global.h"

/* 本文件内函数声明 */
PRIVATE void init_idt_desc(unsigned char vector, t_8 desc_type, t_pf_int_handler handler, unsigned char privilege);

/* 中断处理函数 */
void    divide_error();
void    single_step_exception();
void    nmi();
void    breakpoint_exception();
void    overflow();
void    bounds_check();
void    inval_opcode();
void    copr_not_available();
void    double_fault();
void    copr_seg_overrun();
void    inval_tss();
void    segment_not_present();
void    stack_exception();
void    general_protection();
void    page_fault();
void    copr_error();
void    hwint00();
void    hwint01();
void    hwint02();
void    hwint03();
void    hwint04();
void    hwint05();
void    hwint06();
void    hwint07();
void    hwint08();
void    hwint09();
void    hwint10();
void    hwint11();
void    hwint12();
void    hwint13();
void    hwint14();
void    hwint15();

PUBLIC void init_idt_desc(unsigned char vector, t_8 desc_type, t_pf_int_handler handler, unsigned char privilege)
{
        GATE *  p_gate  = &idt[vector];
        t_32    base    = (t_32)handler;
        p_gate->offset_low      = base & 0xFFFF;
        p_gate->selector        = SELECTOR_KERNEL_CS;
        p_gate->dcount          = 0;
        p_gate->attr            = desc_type | (privilege << 5);
        p_gate->offset_high     = (base >> 16) & 0xFFFF;
}

PUBLIC void init_prot()
{
        init_8259A();

        // 全部初始化成中断门(没有陷阱门)
        init_idt_desc(INT_VECTOR_DIVIDE,        DA_386IGate, divide_error,              PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_DEBUG,         DA_386IGate, single_step_exception,     PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_NMI,           DA_386IGate, nmi,                       PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_BREAKPOINT,    DA_386IGate, breakpoint_exception,      PRIVILEGE_USER);
        init_idt_desc(INT_VECTOR_OVERFLOW,      DA_386IGate, overflow,                  PRIVILEGE_USER);
        init_idt_desc(INT_VECTOR_BOUNDS,        DA_386IGate, bounds_check,              PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_INVAL_OP,      DA_386IGate, inval_opcode,              PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_COPROC_NOT,    DA_386IGate, copr_not_available,        PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_DOUBLE_FAULT,  DA_386IGate, double_fault,              PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_COPROC_SEG,    DA_386IGate, copr_seg_overrun,          PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_INVAL_TSS,     DA_386IGate, inval_tss,                 PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_SEG_NOT,       DA_386IGate, segment_not_present,       PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_STACK_FAULT,   DA_386IGate, stack_exception,           PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_PROTECTION,    DA_386IGate, general_protection,        PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_PAGE_FAULT,    DA_386IGate, page_fault,                PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_COPROC_ERR,    DA_386IGate, copr_error,                PRIVILEGE_KRNL);

        init_idt_desc(INT_VECTOR_IRQ0 + 0,      DA_386IGate, hwint00,                   PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_IRQ0 + 1,      DA_386IGate, hwint01,                   PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_IRQ0 + 2,      DA_386IGate, hwint02,                   PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_IRQ0 + 3,      DA_386IGate, hwint03,                   PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_IRQ0 + 4,      DA_386IGate, hwint04,                   PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_IRQ0 + 5,      DA_386IGate, hwint05,                   PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_IRQ0 + 6,      DA_386IGate, hwint06,                   PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_IRQ0 + 7,      DA_386IGate, hwint07,                   PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_IRQ8 + 0,      DA_386IGate, hwint08,                   PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_IRQ8 + 1,      DA_386IGate, hwint09,                   PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_IRQ8 + 2,      DA_386IGate, hwint10,                   PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_IRQ8 + 3,      DA_386IGate, hwint11,                   PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_IRQ8 + 4,      DA_386IGate, hwint12,                   PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_IRQ8 + 5,      DA_386IGate, hwint13,                   PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_IRQ8 + 6,      DA_386IGate, hwint14,                   PRIVILEGE_KRNL);
        init_idt_desc(INT_VECTOR_IRQ8 + 7,      DA_386IGate, hwint15,                   PRIVILEGE_KRNL);
}

PUBLIC void exception_handler(int vec_no, int err_code, int eip, int cs, int eflags)
{
        int i;
        int text_color = 0x74; /* 灰底红字 */
        char err_description[][64] = {  "#DE Divide Error",
                                        "#DB RESERVED",
                                        "—  NMI Interrupt",
                                        "#BP Breakpoint",
                                        "#OF Overflow",
                                        "#BR BOUND Range Exceeded",
                                        "#UD Invalid Opcode (Undefined Opcode)",
                                        "#NM Device Not Available (No Math Coprocessor)",
                                        "#DF Double Fault",
                                        "    Coprocessor Segment Overrun (reserved)",
                                        "#TS Invalid TSS",
                                        "#NP Segment Not Present",
                                        "#SS Stack-Segment Fault",
                                        "#GP General Protection",
                                        "#PF Page Fault",
                                        "—  (Intel reserved. Do not use.)",
                                        "#MF x87 FPU Floating-Point Error (Math Fault)",
                                        "#AC Alignment Check",
                                        "#MC Machine Check",
                                        "#XF SIMD Floating-Point Exception"
                                };

        /* 通过打印空格的方式清空屏幕的前五行,并把 disp_pos 清零 */
        disp_pos = 0;
        for(i=0;i<80*5;i++){
                disp_str(" ");
        }
        disp_pos = 0;

        disp_color_str("Exception! --> ", text_color);
        disp_color_str(err_description[vec_no], text_color);
        disp_color_str("\n\n", text_color);
        disp_color_str("EFLAGS:", text_color);
        disp_int(eflags);
        disp_color_str("CS:", text_color);
        disp_int(cs);
        disp_color_str("EIP:", text_color);
        disp_int(eip);

        if(err_code != 0xFFFFFFFF){
                disp_color_str("Error code:", text_color);
                disp_int(err_code);
        }
}

 

运行:

OK,中断我们已经基本初始化好了,如果我们想特化某一种中断的处理,直接在相应中断的 call handler 处修改就行,另外,至此,我们的内核雏形已经搭建好了,下一节我们就该奔向进程了...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sssnial-jz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值