Re: How can i load the IDT?
Posted: Mon Jan 02, 2017 7:58 am
Tell us what you understand an interrupt to be, how one is triggered, and how the processor responds. That may help us to understand what your problem is.
The Place to Start for Operating System Developers
http://f.osdev.org/
An interrupt is a piece of data between the 0x0000 - 0x00FF sections of memory that points to a specific address, also called the "interrupt handler".iansjack wrote:Tell us what you understand an interrupt to be, how one is triggered, and how the processor responds. That may help us to understand what your problem is.
The wiki page seems quite clear to me. It provides the structure that you need:NunoLava1998 wrote:An interrupt is a piece of data between the 0x0000 - 0x00FF sections of memory that points to a specific address, also called the "interrupt handler".iansjack wrote:Tell us what you understand an interrupt to be, how one is triggered, and how the processor responds. That may help us to understand what your problem is.
It is triggered using the "int (00-FF)" command.
The processor responds by seeing what the specified interrupt points to, and "calls" that location.
I know how interrupts know, i just want to know how to load the interrupt descriptor table, which i don't know.
Code: Select all
struct IDTDescr {
uint16_t offset_1; // offset bits 0..15
uint16_t selector; // a code segment selector in GDT or LDT
uint8_t zero; // unused, set to 0
uint8_t type_attr; // type and attributes, see below
uint16_t offset_2; // offset bits 16..31
};
Code: Select all
offset_1 = base_address & 0xFFFF;
offset_2 = (base_address >> 16) & 0xFFFF;
OK.NunoLava1998 wrote:An interrupt is a piece of data between the 0x0000 - 0x00FF sections of memory that points to a specific address, also called the "interrupt handler".iansjack wrote:Tell us what you understand an interrupt to be, how one is triggered, and how the processor responds. That may help us to understand what your problem is.
It is triggered using the "int (00-FF)" command.
The processor responds by seeing what the specified interrupt points to, and "calls" that location.
I know how interrupts know, i just want to know how to load the interrupt descriptor table, which i don't know.
I still don't understand a few things:zenzizenzicube wrote:The wiki page seems quite clear to me. It provides the structure that you need:NunoLava1998 wrote:An interrupt is a piece of data between the 0x0000 - 0x00FF sections of memory that points to a specific address, also called the "interrupt handler".iansjack wrote:Tell us what you understand an interrupt to be, how one is triggered, and how the processor responds. That may help us to understand what your problem is.
It is triggered using the "int (00-FF)" command.
The processor responds by seeing what the specified interrupt points to, and "calls" that location.
I know how interrupts know, i just want to know how to load the interrupt descriptor table, which i don't know.You need to create an array of 256 of these, and you pass the address in of the first one to the lidt instruction.Code: Select all
struct IDTDescr { uint16_t offset_1; // offset bits 0..15 uint16_t selector; // a code segment selector in GDT or LDT uint8_t zero; // unused, set to 0 uint8_t type_attr; // type and attributes, see below uint16_t offset_2; // offset bits 16..31 };
Because the address is split into two parts (offset_1 and offset_2), you need to split it up yourself too, like so:Hopefully that clears a little bit up.Code: Select all
offset_1 = base_address & 0xFFFF; offset_2 = (base_address >> 16) & 0xFFFF;
Code: Select all
static inline void lidt(void* base, uint16_t size)
{ // This function works in 32 and 64bit mode
struct {
uint16_t length;
void* base;
} __attribute__((packed)) IDTR = { size, base };
asm ( "lidt %0" : : "m"(IDTR) ); // let the compiler choose an addressing mode
}
void do_lidt(void) {
void *base = (void *)0x10000FF;
uint16_t size = 0x00FF;
lidt(void* base, uint16_t size);
}
Code: Select all
static inline void lidt(void* base, uint16_t size)
{ // This function works in 32 and 64bit mode
struct {
uint16_t length;
void* base;
} __attribute__((packed)) IDTR = { size, base };
asm ( "lidt %0" : : "m"(IDTR) ); // let the compiler choose an addressing mode
}
void do_lidt(void) {
void *base = (void *)0x10000FF;
uint16_t size = 0x00FF;
lidt(base, size);
}
did i cause a M7.5 earthquake or what (sarcasm)alexfru wrote:
glauxosdever wrote:Hi,
Your post count overflowed!
Regards,
glauxosdever
What did you think it was going to do? You point the IDT to a random bit of memory.NunoLava1998 wrote:I just realized the code above is completely wrong (triple faults). Can someone show what to put in? Nothing in the IDT page is clear to me.
So? I wanted to put the IDT in that "random bit of memory" (unused space). I don't need to make space, as it is unused (assuming you always do cold reboots to reset the RAM)iansjack wrote:What did you think it was going to do? You point the IDT to a random bit of memory.NunoLava1998 wrote:I just realized the code above is completely wrong (triple faults). Can someone show what to put in? Nothing in the IDT page is clear to me.