Page 1 of 1
idt setup
Posted: Sat May 31, 2008 1:43 pm
by suthers
To set up my idt, for the moment I have had to do this as an entry:
Code: Select all
id_0:
offset1_0 dw 0
dw 0x08
dw 0x8E00
offset2_0 dw 0
id_1:
offset1_1 dw 0
dw 0x08
dw 0x8E00
offset2_1 dw 0
id_2:
offset1_2 dw 0
dw 0x08
dw 0x8E00
offset2_2 dw 0
etc...
then do this to set it up:
Code: Select all
mov eax, _isr0
mov [offset1_0], ax
shr eax, 16
mov [offset2_0], ax
mov eax, _isr1
mov [offset1_1], ax
shr eax, 16
mov [offset2_1], ax
etc...
This doesn't seem like a very efficient solution as ideally it should be computed during assembly...
I have tried a few preprocessor commands, but failed to do it...
I was wondering how you guys did it and what preprocessor commands i should use to do this.
Thanks in advance,
Jules
P.S. I'm doing a radical re-modeling of my isrs...
edit: P.P.S Just out of interest is there anyway I could improve my posting? (Though this is off topic)
Posted: Sat May 31, 2008 1:55 pm
by neon
I think you need a better interface for your IDT. An IDT is just an array of descriptors, so all you need to do is develop a set_descriptor routine of sorts to set a descriptor.
ie, You can see an example
here of what I am referring to.
In my system, I manage interrupt handlers differently though to allow portability and interrupt chaining.
Posted: Sat May 31, 2008 2:03 pm
by suthers
Thanks thats a good idea, I'll get to work on that.
Since I'm trying to increase its efficiency thats looks like a good idea, but is there really no way to do it through preprocessors?
I would like to do this so to increase efficiency so the idt is almost entirely setup during assembly...
Jules
Posted: Sat May 31, 2008 2:15 pm
by Brendan
Hi,
neon wrote:I think you need a better interface for your IDT. An IDT is just an array of descriptors, so all you need to do is develop a set_descriptor routine of sorts to set a descriptor.
For static IDT descriptors, the code to call the "set_descriptor" routine is larger than the descriptor itself, and probably slower (even if you do a "rep movsd" to shift the descriptors).
Instead (for static IDT descriptors) I'd use a macro. For e.g.:
Code: Select all
%macro IDT_INT_GATE 1
dw (%1) & 0xFFFF
dw KERNEL_CS
dw 0x8E00
dw (%1) >> 16
%endmacro
section .data
myIDTdata:
IDT_INT_GATE _isr0
IDT_INT_GATE _isr1
IDT_INT_GATE _isr2
IDT_INT_GATE _isr3
section .text
However, this macro probably won't work for NASM (you might get a "not a scalar number" error). In that case you might need something like:
Code: Select all
%define ADDRESS_OF_CODE 0x12345678
%macro IDT_INT_GATE 1
dw ( (%1) - $$ + ADDRESS_OF_CODE) & 0xFFFF
dw KERNEL_CS
dw 0x8E00
dw ( (%1) - $$ + ADDRESS_OF_CODE) >> 16
%endmacro
Where "ADDRESS_OF_CODE" has the same value as "$$" (usually the starting address of the ".text" section).
Cheers,
Brendan
Posted: Sat May 31, 2008 2:28 pm
by suthers
if ADDRESS_OF_CODE == $$
can't you just write:
Code: Select all
%macro IDT_INT_GATE 1
dw ( (%1) - ($$ * 2)) & 0xFFFF
dw KERNEL_CS
dw 0x8E00
dw ( (%1) - ($$ * 2)) >> 16
%endmacro
?
Thanks,
Jules
edit: code tags fixed
Posted: Sat May 31, 2008 3:07 pm
by jnc100
@Brendan: Hmm, I get the 'not a scalar error' when I try to use either of your suggestions in yasm or nasm, flat format or elf, and whether the '_isr0' tag is defined extern or within the .text section in the local file. You've obviously got it to work, what am I doing wrong?
suthers wrote:Code: Select all
%macro IDT_INT_GATE 1
dw ( (%1) - ($$ * 2)) & 0xFFFF
dw KERNEL_CS
dw 0x8E00
dw ( (%1) - ($$ * 2)) >> 16
%endmacro
I think you've missed what Brendan was trying to do. Note he does a minus $$ then an add ADDRESS_OF_CODE, the general idea being to try and convert the address '_isr0' to a scalar value by calculating the difference between it and $$ (the beginning of the current section - having thought about it this is why referencing entries in .text from .data doesn't work) and then adding a scalar which you predefine to be the origin of the section containing the handler.
I suggest you go with neon's idea of developing a C routine to do the task. Its portable (at least between compilers) and the speed issue really isn't an issue as it should only ever be called once for each static interrupt (i.e. exception) anyway.
Regards,
John.
Posted: Sat May 31, 2008 4:18 pm
by suthers
Thanks I'll right a routine then.
Any body managed to do it during assembly in nasm though (just out of interest)?
Thanks,
Jules
Posted: Sat May 31, 2008 6:16 pm
by neon
suthers wrote:Thanks I'll right a routine then.
Any body managed to do it during assembly in nasm though (just out of interest)?
Can you describe better at what you mean by "during assembly"? The link I posted goes to a post I made which uses 100% assembly..
Do you mean to dynamically generate the IDT, rather then a global array?
Posted: Sat May 31, 2008 8:21 pm
by Brendan
Hi,
neon wrote:Any body managed to do it during assembly in nasm though (just out of interest)?
I have.
Out of curiosity I tried to assemble my previous macro - it worked without errors. Here's my test code:
Code: Select all
%define ADDRESS_OF_CODE 0x123456
%define KERNEL_CS 0x18
org ADDRESS_OF_CODE
bits 32
%macro IDT_INT_GATE 1
dw ( (%1) - $$ + ADDRESS_OF_CODE) & 0xFFFF
dw KERNEL_CS
dw 0x8E00
dw ( (%1) - $$ + ADDRESS_OF_CODE) >> 16
%endmacro
FOO:
db 1,2,3,4,5
BAR:
db 6,7,8,9,10
IDT_INT_GATE FOO
IDT_INT_GATE BAR
However, Jnc100 is entirely right: it won't work if "$$" is in one section and the label is in another. To get around that you could try something like:
Code: Select all
%define ADDRESS_OF_CODE 0x123456
%define KERNEL_CS 0x18
org ADDRESS_OF_CODE
bits 32
TEXT_START:
%macro IDT_INT_GATE 1
dw ( (%1) - TEXT_START + ADDRESS_OF_CODE) & 0xFFFF
dw KERNEL_CS
dw 0x8E00
dw ( (%1) - TEXT_START + ADDRESS_OF_CODE) >> 16
%endmacro
FOO:
db 1,2,3,4,5
BAR:
db 6,7,8,9,10
section .data
IDT_INT_GATE FOO
IDT_INT_GATE BAR
section .text
This *does* work.
Cheers,
Brendan