构建 IDT(中断描述符表)程序集 AT&T intel 32 位

发布于 2024-12-07 08:56:45 字数 2940 浏览 1 评论 0原文

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

我有一条错误消息: 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;

I try to build an IDT, after sti execution, the code crashes !!

I have an error message :
SingleStep CPU[1] Error : Processor Running

Remark: I use micro Atom with eclipse Helios, the assembly is AT&T

/** *********** New code *********/

New code after I found that the BIOS puts the atom in the protected mode (CR0.PE = 1) and generates IDT/GDT :

The idea is just to use an ISR with APIC timer.

/*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;

}

/*********************End new code *********************/

    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

What is wrong ???

see the rest of the code:

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;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

无戏配角 2024-12-14 08:56:45

您能解释一下为什么将 IDT 条目中的选择器值设置为 0 吗?难道它们不应该更有意义吗?

我不记得细节了(而且现在懒得检查文档),但是将 IDT 条目中的访问字节设置为 0x8E,而不是 0 或 0xEE。那应该有效。您可以稍后将其变得更复杂。

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

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

Can you explain why you set the selector values in IDT entries to 0? Aren't they supposed to be somewhat more meaningful?

I don't remember the details (and am too lazy to check the documentation at the moment), but set your access byte in IDT entries to 0x8E, not 0 or 0xEE. That should work. You can make it more complex later.

Finally, is isr33() a C function or assembly function? Does it save and restore segment registers and general-purpose registers? Show us the function.

Don't enable interrupts yet. First make sure that your isr33 functions properly when invoked through INT 33. Why? Having seen the above, I anticipate issues with the PIC configuration and handling and any hardware interrupt can just crash your code if the PIC is not programmed correctly.

思慕 2024-12-14 08:56:45

已解决,当我使用 N450 Atom 板时,它已经有一个 BIOS,BIOS 生成 IDT 和 GDT,我所要做的就是通过使用 sidt(用于 IDT)和 sgdt 读取他们的地址来了解它们现在的位置(对于 GDT)。

Resolved, As I use a N450 Atom board, it has already a BIOS, the BIOS makes the IDT and GDT, all I have to do it is just to now where they are by reading thier adressess with : sidt (for IDT) and sgdt (for GDT).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文