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
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
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.
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
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.