开发者

Build an IDT (INTERRUPT DESCRIPTOR TABLE) assembly AT&T intel 32 bits

开发者 https://www.devze.com 2023-04-10 00:48 出处:网络
I try to build an IDT, after sti execution, the code crashes !! I have an error message : SingleStep CPU[1] Error : Processor Running

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;


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.


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).

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号