构建IDT(INTERRUPT DESCRIPTOR TABLE)组件AT& T intel 32位

时间:2011-09-30 21:22:39

标签: assembly

我尝试构建一个IDT,在执行后,代码崩溃!!

我有一条错误消息: SingleStep CPU [1]错误:处理器正在运行

备注:我使用micro Atom和eclipse Helios,程序集是AT& T

/ ** ** * ** * ** * ** 新代码 * ** * ** * * * /

我发现BIOS将原子置于保护模式(CR0.PE = 1)并生成IDT / GDT之后的新代码:

这个想法只是使用带有APIC计时器的ISR。

/*Change the address of idt_entries table */
fill_interrupt(ISR_Nbr,(unsigned int) isr33, 0x08, 0x8E);


static void fill_interrupt(unsigned char num, unsigned int base, unsigned short sel, unsigned char flags)
{
    unsigned short *Interrupt_Address;

    /*address = idt_ptr.base + num * 8 byte*/
    Interrupt_Address = (unsigned short *)(idt_ptr.base + num*8);

    *(Interrupt_Address) = base&0xFFFF;
    *(Interrupt_Address+1) = sel;
    *(Interrupt_Address+2) = (flags<<4)&0xFF00;
    *(Interrupt_Address+3) = (base>>16)&0xFFFF;

}

/ * ** * ** * ** * ** * ** * ** * ** 结束新代码 ** * ** * ** * ** * ** * ** * ** * /

    idt_flush:
push %ebp   //save the context to swith back
mov %esp,%ebp

cli

mov $idt_ptr, %eax //Get the pointer to the IDT, passed as parameter
lidt    (%eax)         //Load the IDT pointer

sti

pop %ebp               //Return to the calling function
ret

有什么问题???

请参阅其余代码:

isr33:
    push %ebp   //save the context to swith back
    mov %esp,%ebp




    pop %ebp //Return to the calling function
    ret


static void init_idt()
{
    int iIndex;


    //Link the IDTR to IDT
    idt_ptr.limit = sizeof(idt_entry_t)*256-1;
    idt_ptr.base = (unsigned int)&idt_entries;

    idt_set_gate(0,(unsigned int) isr0, 0x00, 0xEE);
    for ( iIndex=1; iIndex<32; iIndex++)
    {
        idt_set_gate(iIndex,(unsigned int) isr0, 0x00, 0x00);

    }
    idt_set_gate(ISR_Nbr,(unsigned int) isr33, 0x00, 0xEE);

    //idt_flush((unsigned int)&idt_ptr);
    idt_flush();

}

static void idt_set_gate(unsigned char num, unsigned int base, unsigned short sel, unsigned char flags)
{
    idt_entries[num].base_lo = base&0xFFFF;
    idt_entries[num].base_hi = (base>>16)&0xFFFF;

    idt_entries[num].sel = sel;
    idt_entries[num].always0 = 0;

    idt_entries[num].flags = flags;
}



//IDT
struct idt_entry_struct
{
    unsigned short base_lo;
    unsigned short sel;
    unsigned char always0;
    unsigned char flags;
    unsigned short base_hi;
}__attribute__((packed));
typedef struct idt_entry_struct idt_entry_t;

//IDT register
struct idt_ptr_struct
{
    unsigned short limit;
    unsigned int base;
}__attribute__((packed));
typedef struct idt_ptr_struct idt_ptr_t;

//ISR number
int ISR_Nbr = 33;

2 个答案:

答案 0 :(得分:2)

您能解释为什么将IDT条目中的选择器值设置为0吗?他们不应该有点意义吗?

我不记得详细信息(我现在懒得检查文档),但是将IDT条目中的访问字节设置为0x8E,而不是0或0xEE。这应该工作。你以后可以把它变得更复杂。

最后,isr33()是C函数还是汇编函数?它是否保存和恢复段寄存器和通用寄存器?向我们展示这个功能。

不要启用中断。首先确保通过INT 33调用isr33正常运行。为什么?看到上述内容后,我预计PIC配置和处理会出现问题,如果没有正确编程PIC,任何硬件中断都可能导致代码崩溃。

答案 1 :(得分:0)

已解决,因为我使用的是N450 Atom主板,它已经有了BIOS,BIOS就是IDT和GDT,所有我必须要做的只是到现在他们通过阅读他们的地址:sidt(对于IDT) )和sgdt(对于GDT)。