idt setup

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
suthers
Member
Member
Posts: 672
Joined: Tue Feb 20, 2007 3:00 pm
Location: London UK
Contact:

idt setup

Post 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)
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Post 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.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
User avatar
suthers
Member
Member
Posts: 672
Joined: Tue Feb 20, 2007 3:00 pm
Location: London UK
Contact:

Post 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
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Post 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
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
User avatar
suthers
Member
Member
Posts: 672
Joined: Tue Feb 20, 2007 3:00 pm
Location: London UK
Contact:

Post 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
jnc100
Member
Member
Posts: 775
Joined: Mon Apr 09, 2007 12:10 pm
Location: London, UK
Contact:

Post 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.
User avatar
suthers
Member
Member
Posts: 672
Joined: Tue Feb 20, 2007 3:00 pm
Location: London UK
Contact:

Post 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
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Post 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?
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Post 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
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Post Reply