我尝试构建一个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;
答案 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)。