+ -
当前位置:首页 → 问答吧 → x86 保护模式回到实模式,8259A 中断控制器不工作

x86 保护模式回到实模式,8259A 中断控制器不工作

时间:2011-04-09

来源:互联网

具体过程是这样的:

自己写了一个 loader,用来在 DOS 下面装入 32 位代码执行。
因为保护模式下 0x1F 以下的中断号都被系统保留了,所以需要重新设置 8259A 中断控制器的偏移为 0x20。
到这里为止一切正常,保护模式下可以接受各种硬件中断。
可是程序结束返回到 DOS 的时候悲剧了,尽管已经把 8259A 的中断向量偏移重新设成了 0x08,可是这东西就和死了一样,什么反应都没有……
退回实模式后,返回 DOS 之前,软件触发 int 0 可以看到 Divide overflow,说明 IDT 是正确的。

难道是我搞错了?实模式下的中断向量偏移不是 0x08?还是 8259A 的其他什么参数没配置好?
求解答……

相关代码:
C/C++ code
void setup_8259a(uint8_t int_offset)
{
    // 主从模式,边缘触发,使用 ICW4,interval = 8
    outb(0x20, 0x11);
    io_delay();
    outb(0xa0, 0x11);
    io_delay();
    
    // 设置主 8259A 偏移
    outb(0x21, int_offset & ~0x7);
    io_delay();
    // 设置从 8259A 偏移
    outb(0xa1, (int_offset & ~0x7) + 0x8);
    io_delay();
    
    // 从片连接在 IR2 上
    outb(0x21, 0x4);
    io_delay();
    outb(0xa1, 0x2);
    io_delay();
    
    // 设置自动 EOI
    outb(0x21, 0x3);
    io_delay();
    outb(0xa1, 0x1);
    io_delay();
}

void set_imr(uint16_t mask)
{
    outb(0x21, mask & 0xff);
    io_delay();
    outb(0xa1, (mask >> 8) & 0xff);
    io_delay();
}



进入保护模式时调用
C/C++ code
    setup_8259a(0x20);
    set_imr(0b1111111111111100);


离开保护模式之前调用
C/C++ code
    setup_8259a(0x8);
    set_imr(0);

作者: hpsmouse   发布时间: 2011-04-09

= =楼主学的是哪本书啊,我才学了王爽的,也想学学实模式

作者: A328240784   发布时间: 2011-04-10