构建 IDT(中断描述符表)程序集 AT&T intel 32 位
我尝试构建一个 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您能解释一下为什么将 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.已解决,当我使用 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).