Page 1 of 2

Point a struct to a specific address

Posted: Thu Feb 14, 2008 2:26 pm
by AlfaOmega08
I'm trying to put my GDTR struct (in C++) to the address 0x500.

How should I declare the struct to do this

Thanks in advance

Posted: Thu Feb 14, 2008 2:30 pm
by t0xic

Code: Select all

gdtr_t *gdt = (gdtr_t*) 0x500;
Might I suggest this and this

--Michael

Posted: Thu Feb 14, 2008 2:46 pm
by AlfaOmega08
I've already readed a bit of that pages...

I've also already tried the solution you posts. Now GCC, each time I try to modify an element in the struct gives me an error like:

Code: Select all

gdt.cpp:36: error: request for member ‘base’ in ‘GDTr’, which is of non-class type ‘GDTRegister*’
GDTRegister is the name of the type of struct, GDTr is the name of the struct, and base is the element.

This is how I declared GDTRegister:

Code: Select all

typedef struct GDTR {
	Bit16u	limit;
	Bit32u	base;
} GDTRegister;

Posted: Thu Feb 14, 2008 2:53 pm
by Combuster
at the very least, post the line that's causing the error, if not more.

Posted: Thu Feb 14, 2008 3:05 pm
by AlfaOmega08
Each line with access to the struct gives error. Eg:

Code: Select all

	GDTr.base = (Bit32u) &GDT;
	GDTr.limit = 0;
[/code]

Posted: Thu Feb 14, 2008 3:35 pm
by Combuster
use -> instead of .

Posted: Fri Feb 15, 2008 2:34 am
by AJ
Hi,

Why not simply declare GDTr as a struct rather than a struct pointer and not worry about it being at 0x500? Then, just pass &GDTr when you LGDT.

Cheers,
Adam

Posted: Fri Feb 15, 2008 7:03 am
by AlfaOmega08
combuster wrote:use -> instead of .
It gives me the same error...
AJ wrote:just pass &GDTr when you LGDT
I was trying to put GDTr because the method you have posted, doesn't works for me...

When I LGDT, bochs loads a GDT with base = 0 and limit = 65535 than crashes before I can update the segment registers

Posted: Mon Feb 18, 2008 10:56 am
by JAAman
AlfaOmega08 wrote: When I LGDT, bochs loads a GDT with base = 0 and limit = 65535 than crashes before I can update the segment registers
that sounds like you forgot to disable interrupts...

if interrupts arnt disabled, it will try to fire one, and crash, because the IDT is invalid for PMode (assuming it crashes after entering PMode -- you didnt specify, but did imply that... doesnt make sense that it would crash before that anyway...)

Posted: Fri Feb 22, 2008 7:06 am
by JamesM
combuster wrote:
use -> instead of .
It gives me the same error...
Are you certain? because that is the correct fix for the error you're seeing.

May I humbly suggest that you learn your language better? This is simple beginner's stuff.

Posted: Fri Feb 22, 2008 11:22 am
by 01000101
uhh, why wouldn't this work?

Code: Select all

struct gdt_ptr
{
    unsigned short limit;
    unsigned int base;
} __attribute__((packed));


struct gdt_ptr *pGDT;

int main()
{
    pGDT = 0x500; // new address of STRUCT gdt_ptr
                           // pGDT->limit is now at 0x500;
                           // pGDT->base is now at 0x502;

    pGDT->limit = 0x1234;
    pGDT->base = 0x5678;
the above would put STRUCT gdt_ptr @ 0x500, and assign dummy values to limit and base. you can alter there placement with the '&' prefix.

Posted: Mon Feb 25, 2008 1:27 am
by Solar
Gosh, look at all this helpful information, as to what supposedly doesn't work...

You probably refer to the segfault? Did you check in which line that segfault occurs, for example using a debugger?

Code: Select all

$ gcc -g test.c
$ gdb a.out
(gdb) break main
(gdb) run
Starting program: a.out 

Breakpoint 1, main () at test.c:14
14          pGDT = (struct gdt_ptr *) 0x500; // new address of STRUCT gdt_ptr
(gdb) step
(gdb) step
17          pGDT->limit = 0x1234;
(gdb) step

Program received signal SIGSEGV, Segmentation fault.
0x0001068c in main () at test.c:17
17          pGDT->limit = 0x1234;
(gdb)
So, it chokes when you write 0x1234 at memory address 0x500. Could this be, perhaps, because 0x500 does not represent a struct gdt_ptr just because you pointed a pointer at it?

Code: Select all

#include <assert.h>

struct gdt_ptr
{
    unsigned short limit;
    unsigned int base;
} __attribute__((packed));


struct gdt_ptr *pGDT;

int main()
{
    pGDT = (struct gdt_ptr *) 0x500;
    assert( pGDT == (void *)0x500 );
    assert( &(pGDT->limit) == (void *)0x500 );
    assert( &(pGDT->base) == (void *)0x502 );
    return 0;
}
This compiles and runs correctly. Try improving your grasp on elementary debugging, pointers, and how accessing memory works.

Posted: Mon Feb 25, 2008 9:30 pm
by 01000101
wow, nice snap to a rhetorical question.

the code that I posted does work. Compiled fine under GCC and have even used that implementation in one of my previous kernels.

Posted: Tue Feb 26, 2008 7:22 am
by Solar
01000101 wrote:the code that I posted does work. Compiled fine under GCC and have even used that implementation in one of my previous kernels.
The code you extracted your post from, perhaps. Taking the code from your post, adding a return 0; and a closing bracket, gives a compiler warning and segfaults when being run.

Posted: Tue Feb 26, 2008 7:27 am
by JamesM
Solar wrote:
01000101 wrote:the code that I posted does work. Compiled fine under GCC and have even used that implementation in one of my previous kernels.
The code you extracted your post from, perhaps. Taking the code from your post, adding a return 0; and a closing bracket, gives a compiler warning and segfaults when being run.
Solar:

The code is changing a GDT. What makes you think it is designed to be run in a hosted environment? Of course under linux 0x500 is an invalid address, but it probably isn't in the OP's OS...