2002-04-05 18:30:52

by halfdead

[permalink] [raw]
Subject: weird IDT issue

hey! i experience a weird IDT issue on kernels 2.4.x. what i want to do is
finding the address of a certain IDT gate but when i try to read memory
from ring0 at that location it segfaults. the code is in assembler.

.bss
idtr:
.double
.text

get_gate:
movl $0x80, %eax
sidt idtr
movl idtr+2, %ebx
leal (%ebx, %eax, 8), %ebx
movw (%ebx), %cx <- segfault

i cannot find out why is this happening.. i would apreciate any help that
i can get.

- halfdead


2002-04-05 20:39:59

by halfdead

[permalink] [raw]
Subject: Re: weird IDT issue

first of all, i get the correct idt base. the problem is i cannot
dereference it, to get the interrupt entry i`m interrested in. second, i
have tried to get the right segment by pushl %ss / popl %ds . it has the
same behaviour. i would apreciate if you`d be more clear .. thanks in
advance for your help.

- halfdead


2002-04-05 20:26:45

by Richard B. Johnson

[permalink] [raw]
Subject: Re: weird IDT issue

On Fri, 5 Apr 2002, halfdead wrote:

> hey! i experience a weird IDT issue on kernels 2.4.x. what i want to do is
> finding the address of a certain IDT gate but when i try to read memory
> from ring0 at that location it segfaults. the code is in assembler.
>
> .bss
> idtr:
> .double
> .text
>
> get_gate:
> movl $0x80, %eax
> sidt idtr

# Store contents of IDT into idtr, in space you own. Okay so far even
though '.double' isn't correct. It should be:

.section .bss
idtr: .long[2]
.section .text

> movl idtr+2, %ebx

This should put the PHYSICAL address of the base into ebx.

> leal (%ebx, %eax, 8), %ebx

Now you are going to sum the physical address in ebx with 0x80 and 8
index, putting the result into ebx. Hmmm...

> movw (%ebx), %cx <- segfault
>

Now you are going to access something in some strange location that
is either not mapped or you don't own.

> i cannot find out why is this happening.. i would apreciate any help that
> i can get.
>
> - halfdead
>

In the first place, addresses in the IDT are physical. They are mapped
in an area where there is a 1:1 correspondence between virtual and
physical. You either need to set DS to that descriptor before you
access (where the page-table is, I forget its name) it or mmap that
address so you can access it.

Cheers,
Dick Johnson

Penguin : Linux version 2.4.18 on an i686 machine (797.90 BogoMips).

Windows-2000/Professional isn't.

2002-04-05 22:15:10

by halfdead

[permalink] [raw]
Subject: Re: weird IDT issue

i am afraid that is not really necessary(to OR in PAGE_OFFSET) because the
address i get from my code as being the address of IDT is at 0xc3800000,
which seems to be as virtual memory. greetz!

- halfdead

2002-04-05 21:18:09

by Richard B. Johnson

[permalink] [raw]
Subject: Re: weird IDT issue

On Fri, 5 Apr 2002, halfdead wrote:

> first of all, i get the correct idt base. the problem is i cannot
> dereference it, to get the interrupt entry i`m interrested in. second, i
> have tried to get the right segment by pushl %ss / popl %ds . it has the
> same behaviour. i would apreciate if you`d be more clear .. thanks in
> advance for your help.
>
> - halfdead

Well no. All addresses in the kernel are virtual addresses. You got
a number, which seemed like the correct place, but that number does
not represent the virtual address at which it can be accessed. For
starters, take that number and OR in PAGE_OFFSET. This is a way of
cheating, it is not the correct way, but you can then dereference
the resulting pointer (for experimental use only, standard disclaimers
apply).

Cheers,
Dick Johnson

Penguin : Linux version 2.4.18 on an i686 machine (797.90 BogoMips).

Windows-2000/Professional isn't.