内核--中断处理部分【1】——初始化8259A

来源:百度文库 编辑:神马文学网 时间:2024/04/30 01:00:05
内核--中断处理部分【1】——初始化8259A 

    我们的内核要实现多任务处理,就必须要有一个任务的切换机制:时钟中断,
所以下一步工作就是在内核中加入中断处理.
    保护模式的中断处理与实模式很不一样,我们首先要初始化8259A中断控制器,
还要建立中断描述符表IDT.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;保护模式的中断处理:
        [1]中断描述符表
        [2]初始化8259A

;;;;{1}先来说初始化8259A,因为这个很简单.
    ;;;;[1]PC中的8259A是两片级联的,分为主片和从片,对应的端口如下:
            主:0x20和0x21
            从:0xa0和0xa1
    ;;;;[2]具体的8259A初始化过程就是向这些端口中写入:
                ICW(Initialization Command Word)
                OCW(Opration Control Word)
            ICW共4个,OCW有3个(但我们只知道2个),他们都是8位.
           
        ;;;;ICW
            ;;;;-------------------------------------------------
            ;;out 0x20, 0x11
            ;;out 0xa0, 0x11
            ;;ICW1 -> 主0x20,从0xa0
            ;;    [0]: 0=不需要ICW4,1=需要ICW4
            ;;    [1]: 0=级联8259,1=单个8259
            ;;    [2]: 0=8字节中断向量,1=4字节中断向量
            ;;    [3]: 0=edge triggered模式,1=level triggered模式
            ;;    [4]: 对ICW1必须为1,端口必须为0x20或0xa0
            ;;    [5]: ---\
            ;;    [6]: ----> 对PC系统都为0
            ;;    [7]: ---/
            ;;;;-------------------------------------------------
            ;;out 0x21, 0x20
            ;;out 0xa1, 0x28
            ;;ICW2 -> 主0x21,从0xa1
            ;;    [0-2]: 80x86系统全为0
            ;;    [3-7]: 80x86系统中断向量
            ;;;;-------------------------------------------------
            ;;out 0x21, 0x04
            ;;out 0xa1, 0x02
            ;;ICW3 -> 主0x21
            ;;    级联标志位,若第n位为1,表示IRn级联从片;0,表示无从片
            ;;    例:IR2级联从片,则主片ICW3=0x04
            ;;ICW3 -> 从0xa1
            ;;    [0-2]: 从片连接的主片IR号,主片IR2级联从片,则ICW3=0x02
            ;;    [3-7]: 全部为0
            ;;;;-------------------------------------------------
            ;;out 0x21, 0x01
            ;;out 0xa1, 0x01
            ;;ICW4 -> 主0x21,从0xa1
            ;;    [0]: 0=MCS 80/85,1=8086模式
            ;;    [1]: 0=正常EOI,1=自动EOI
            ;;    [2-3]: 主从缓冲模式
            ;;    [4]: 0=sequential模式,1=SFNM模式
            ;;    [5-7]: 未使用,全为0

        ;;;;OCW
            ;;;;-------------------------------------------------
            ;;out 0x21, 0xff    ;屏蔽主8259A的所有外部中断
            ;;out 0xa1, 0xff    ;屏蔽从8259A的多有外部中断
            ;;OCW1 -> 主0x21,从0xa1
            ;;    屏蔽或打开外部中断,若第n位为1则表示关闭IRQn;为0则表示打开IRQn
            ;;;;-------------------------------------------------
            ;;out 0x20(或0xa0), 0x20    ;发送EOI,通知主或从8259A中断处理结束
            ;;OCW2 -> 主0x20,从0xa0
            ;;    [0]: L0
            ;;    [1]: L1
            ;;    [2]: L2
            ;;    [3]: 0
            ;;    [4]: 0
            ;;    [5]:EOI
            ;;    [6]:SL
            ;;    [7]:R

    ;;;;[3]相关C语言代码:
            主从中断控制器端口定义:
            #define I8259A_M_CTRL 0x20
            #define I8259A_M_CTRLMASK 0x21
            #define I8259A_S_CTRL 0xa0
            #define I8259A_S_CTRLMASK 0xa1

            中断向量号定义:
            /* 主8259A中断向量号定义 */
            #define INT_VECTOR_8259_M_IRQ0 0x20
            /* 从8259A中断向量号定义 */
            #define INT_VECTOR_8259_S_IRQ0 0x28

            8259A初始化函数init_8259A():
            PUBLIC void init_8259A()
            {
                /*ICW1*/
                outb(INT_M_CTRL, 0x11);        /*主ICW1*/
                outb(INT_S_CTRL, 0x11);        /*从ICW1*/
                /*ICW2*/
                outb(INT_M_CTRLMASK, INT_VECTOR_IRQ0);    /*主片自IRQ0开始*/
                outb(INT_S_CTRLMASK, INT_VECTOR_IRQ8);    /*从片自IRQ8开始*/
                /*ICW3*/
                outb(INT_M_CTRLMASK, 0x04);    /*IR2级联从片*/
                outb(INT_S_CTRLMASK, 0x02);    /*从片连接主片IR2*/
                /*ICW4*/
                outb(INT_M_CTRLMASK, 0x01);
                outb(INT_S_CTRLMASK, 0x01);
                /*OCW1*/
                outb(INT_M_CTRL, 0xff);        /*屏蔽主片所有外部中断*/
                outb(INT_S_CTRL, 0xff);        /*屏蔽从片所有外部中断*/
            }