Build an IDT (INTERRUPT DESCRIPTOR TABLE) assembly AT&T intel 32 bits
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).
精彩评论