Setting Up the IDT from C
Setting Up the IDT from C
Couple things about setting up the idt from C:
1.) Should it be done before or after paging is enabled
2.) Will the & operator suffice in calculating the isr's address, or is it relative to something else.
3. ) (not really significant) why does intel seperate the address into two words as opposed to one 32-bit entry, then put the rest behind it.
1.) Should it be done before or after paging is enabled
2.) Will the & operator suffice in calculating the isr's address, or is it relative to something else.
3. ) (not really significant) why does intel seperate the address into two words as opposed to one 32-bit entry, then put the rest behind it.
Re:Setting Up the IDT from C
I don't think it matters wether you do it before or after to be honest i have done both and seem to work. I would personal enable it after paging, this makes more sense to me. Im sure soemone will come on and give a good reason why to do it before as well.
If you head over to Bona Fide OS dev there is a tutuorial on IDT's and that has a really good example kernel you can download.
Peter
If you head over to Bona Fide OS dev there is a tutuorial on IDT's and that has a really good example kernel you can download.
Peter
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:Setting Up the IDT from C
i would do it before so that a page fault triggered while enabling the paging will be caught and reported. The sooner you'll have a "kernel panic" report working, the less tricky debugging sessions you will have...shad wrote: Couple things about setting up the idt from C:
1.) Should it be done before or after paging is enabled
because GDT, LDT, IDT, etc. initially come from the 286 which had 16-bits limit and 24-bits base (iirc)3. ) (not really significant) why does intel seperate the address into two words as opposed to one 32-bit entry, then put the rest behind it.
Re:Setting Up the IDT from C
ok sounds good. i saw in some pmode examples bt Chris Giese that the entry point of the idt entry was set to the function name, but the other bits (of the entry point) werent set, why is that? Also, if the idt is done from C, what is the address of the function relative to? Will this work:
theres a ptr to the addr of the idt, say 0x10000 (arbitrary).
*idtptr = &offset
idtptr += 6;
*iptr = &offset >> 16;
theres a ptr to the addr of the idt, say 0x10000 (arbitrary).
*idtptr = &offset
idtptr += 6;
*iptr = &offset >> 16;
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:Setting Up the IDT from C
keep in mind that increasing a pointer by N will move it N*sizeof(base_type) bytes further.
If you do
(note that the unary & operator isn't mandatory before a function identifier, but that "&0xFFFF" is in order to drop higher bits), then "idtptr" is likely to be a unsinged short *idtptr
In which case, you should do and not *(idtptr+6) !
If you still doubt the compiler did it properly, just ask a disassembly (gcc -S idt.c -I <include path>) to check the generated code is what you wish.
If you do
Code: Select all
*idptr = offset & 0xFFFF;
In which case, you should do
Code: Select all
*(idtptr+3)=offset>>16;
If you still doubt the compiler did it properly, just ask a disassembly (gcc -S idt.c -I <include path>) to check the generated code is what you wish.
Re:Setting Up the IDT from C
ok this makes sense.
But once all the entries and what not are there, how do you load it?
But once all the entries and what not are there, how do you load it?
Re:Setting Up the IDT from C
LIDTshad wrote: ok this makes sense.
But once all the entries and what not are there, how do you load it?
This instruction isn't replicated in C so you'll have to do it with inline ASM.
Re:Setting Up the IDT from C
Still cant get it to work. Bochs returns saying "interrupt(): not valid sys seg" or something to that effect.
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:Setting Up the IDT from C
Hmmm... For sure, the whole descriptor for every interrupt you use has to be fully described. Including type field, offset and code selector.
I would bet that in the program you inspire from, type and selector were initialized as static data (thus the IDT was just missing offsets) because offsets computations are tricky (if not impossible) at compile time. So it has run-time code that fills a prepared IDT with offsets ...
If you just use the run-time code without the prepared datas, you're running towards the Evil Land of General Protection Fault
I would bet that in the program you inspire from, type and selector were initialized as static data (thus the IDT was just missing offsets) because offsets computations are tricky (if not impossible) at compile time. So it has run-time code that fills a prepared IDT with offsets ...
If you just use the run-time code without the prepared datas, you're running towards the Evil Land of General Protection Fault
Re:Setting Up the IDT from C
Ok. I figured out why my lidt and lgdt arent working... but im not sure how to fix it. When i run bochs, and set a breakpoint after my lgdt, the gdtr regs holds the correct limit, but the base seems to be the offset << 16... why is that?
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:Setting Up the IDT from C
would you by any chance have defined gdtr.limit as a DD (double word, or INT in 32bits C) ?
It is supposed to be a single word (DW in asm or short in 32-bits C). If you declare it as a DD, then its higher 16 bits (expected 0) will be used as the lower 16 bits of the base, and the base will appear <<16 ...
It is supposed to be a single word (DW in asm or short in 32-bits C). If you declare it as a DD, then its higher 16 bits (expected 0) will be used as the lower 16 bits of the base, and the base will appear <<16 ...