visit GDT and IDT under UEFI?

Programming, for all ages and all languages.
Post Reply
wyj
Posts: 11
Joined: Thu Nov 27, 2014 8:23 pm

visit GDT and IDT under UEFI?

Post by wyj »

I do that by this:
in file systemlib.asm:
global save_gdt
save_gdt:
sgdt [rcx]
ret
just like this

in file uefi_main.c:
extern __int64 __fastcall save_gdt(GDTR_t*);
extern __int64 __fastcall load_gdt(GDTR_t*);
extern __int64 __fastcall save_idt(IDTR_t*);
extern __int64 __fastcall load_idt(IDTR_t*);
......
IDTR_t idtr;
idtr.addr = 0;
idtr.limit = 0;
save_idt(&idtr);

sth. like that,but I what I get is
GDT starts at 0x0 and ends at 0x3F, all empty
IDT starts at 0x0 and ends at 0xFFF, all empty again

I understand GDT is usually useless under long mode,
but doesn't my UEFI BIOS use interruption ?
Am I doing it right ?
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: visit GDT and IDT under UEFI?

Post by Brendan »

Hi,

For fun, fill your "GDTR_t" with trash (e.g. base = 0x55AA55AA55AA55AA, limit = 0x55AA) and then call "save_gdt()".

This will help determine if you're saving the GDTR properly, or just reading "random zeros" because you're not saving GDTR properly or because you forgot to pack the structure or something.


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.
wyj
Posts: 11
Joined: Thu Nov 27, 2014 8:23 pm

Re: visit GDT and IDT under UEFI?

Post by wyj »

Brendan wrote:Hi,

For fun, fill your "GDTR_t" with trash (e.g. base = 0x55AA55AA55AA55AA, limit = 0x55AA) and then call "save_gdt()".

This will help determine if you're saving the GDTR properly, or just reading "random zeros" because you're not saving GDTR properly or because you forgot to pack the structure or something.


Cheers,

Brendan
indeed I filled it with zeros as shown above, and at least the gdtr.limit changed after the call

and the GDTR_t is defined as this:
typedef struct {
__int16 limit;
__int64 addr;
}GDTR_t;
and IDTR_t is just the same
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: visit GDT and IDT under UEFI?

Post by Brendan »

Hi,
wyj wrote:and the GDTR_t is defined as this:
typedef struct {
__int16 limit;
__int64 addr;
}GDTR_t;
and IDTR_t is just the same
That's not packed; so the compiler will probably add an extra 6 bytes of padding between "limit" and "addr" (so that "addr" is aligned nicely) and cause it to be wrong. ;)

Try something more like:

Code: Select all

typedef struct {
	__int16 limit;
	__int64 addr;
} __attribute__(packed) GDTR_t;

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.
wyj
Posts: 11
Joined: Thu Nov 27, 2014 8:23 pm

Re: visit GDT and IDT under UEFI?

Post by wyj »

Brendan wrote:Hi,
wyj wrote:and the GDTR_t is defined as this:
typedef struct {
__int16 limit;
__int64 addr;
}GDTR_t;
and IDTR_t is just the same
That's not packed; so the compiler will probably add an extra 6 bytes of padding between "limit" and "addr" (so that "addr" is aligned nicely) and cause it to be wrong. ;)

Try something more like:

Code: Select all

typedef struct {
	__int16 limit;
	__int64 addr;
} __attribute__(packed) GDTR_t;

Cheers,

Brendan
It works, thank you.
and for me I choose to #include<packon.h>,which is in the gnu-efi package.
Post Reply