Point a struct to a specific address

Programming, for all ages and all languages.
User avatar
AlfaOmega08
Member
Member
Posts: 226
Joined: Wed Nov 07, 2007 12:15 pm
Location: Italy

Point a struct to a specific address

Post 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
User avatar
t0xic
Member
Member
Posts: 216
Joined: Sat May 05, 2007 3:16 pm
Location: VA
Contact:

Post by t0xic »

Code: Select all

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

--Michael
User avatar
AlfaOmega08
Member
Member
Posts: 226
Joined: Wed Nov 07, 2007 12:15 pm
Location: Italy

Post 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;
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

at the very least, post the line that's causing the error, if not more.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
AlfaOmega08
Member
Member
Posts: 226
Joined: Wed Nov 07, 2007 12:15 pm
Location: Italy

Post by AlfaOmega08 »

Each line with access to the struct gives error. Eg:

Code: Select all

	GDTr.base = (Bit32u) &GDT;
	GDTr.limit = 0;
[/code]
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

use -> instead of .
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Post 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
User avatar
AlfaOmega08
Member
Member
Posts: 226
Joined: Wed Nov 07, 2007 12:15 pm
Location: Italy

Post 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
User avatar
JAAman
Member
Member
Posts: 879
Joined: Wed Oct 27, 2004 11:00 pm
Location: WA

Post 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...)
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post 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.
User avatar
01000101
Member
Member
Posts: 1599
Joined: Fri Jun 22, 2007 12:47 pm
Contact:

Post 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.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Post 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.
Every good solution is obvious once you've found it.
User avatar
01000101
Member
Member
Posts: 1599
Joined: Fri Jun 22, 2007 12:47 pm
Contact:

Post 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.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Post 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.
Every good solution is obvious once you've found it.
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

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