Page 1 of 1
GDT crash...
Posted: Thu Oct 31, 2002 8:46 am
by Zi
I'm trying to do an operating system. It the final project of my studies. So it's very important for me. I've done a boot sector, and i've passed in protected mode, with a reinitialization of the GDT. I'm writing my kernel in C, I want to reinitalize the GDT a second time. And this code reboots my PC... I don't know why... I send you the code. It crashes when I put init_gdt() in the main program.
Code: Select all
typedef struct s_entree_GDT
{
unsigned short limit15_00;
unsigned short base15_00;
unsigned char base23_16;
unsigned char type;
unsigned char type_util;
unsigned char base31_24;
} t_entree_gdt;
// La GDT peut avoir au plus 8192 segments...
//struct s_entree_GDT GDT[128];
t_entree_gdt GDT[128];
// Fonction permettant de charger la GDT (page 3-8)
void _lgdt(void * base, unsigned long limit)
{
unsigned long i[2];
i[0] = limit << 16;
i[1] = (unsigned long) base;
print("\n");
__asm__ __volatile__ ("lgdt (%0)": :"p" (((char *) i)+2));
print("GDT charg?e\n");
asm volatile("jmp reinit_cs\n \
reinit_cs:\n \
movl $0x10,%eax\n \
movw %ax,%ds\n \
movw %ax,%es\n \
movw %ax,%fs\n \
movw %ax,%gs\n \
movw %ax,%ss\n");
}
/**
* D?finit un descripteur de la GDT
**/
void set_gdt_desc(int num, long base, long limite, char G, char DB, char AVL,
char present, char DPL, char S, char t)
{
// CF page 3-10 du tome 3 du IA-32 Intel Architecture Software Developer's Manual.
GDT[num].limit15_00 = limite & 0xFFFF;
GDT[num].base15_00 = base & 0xFFFF;
GDT[num].base23_16 = (base >> 16) & 0xFF;
GDT[num].type = t & 0xF | ((present * 0x8 + DPL * 2 + S)<<8)&0xF0;
GDT[num].type_util = (limite >> 16) & 0xF + ((AVL + DB*4 + G*8)<<8)&0xF0;
GDT[num].base31_24 = (base >> 24) & 0xFF;
}
void init_gdt(void)
{
set_gdt_desc(0,0,0,0,0,0,0,0,0,0);
/* Le bouquin Intel est clair : le 1er descripteur
* doit ?tre enti?rement ? 0. D'o? cette ligne.
*/
set_gdt_desc(1,0,0xFFFFF,1,1,0,1,1,1,0xB); // CS
set_gdt_desc(2,0,0xFFFFF,1,1,0,1,1,1,0x7); // DS
_lgdt(GDT,0x3FF);
}
This is... I've got the same configuration of the GDT before the lgdt call... That's wath I can't understand...
Thanks.
Damien Szczyt
Re:GDT crash...
Posted: Thu Oct 31, 2002 9:01 am
by Pype.Clicker
i suggest you use unsigned longs for limit & base parameters, as (a.f.a.i.k.) C doesn't define whether 0xffff ffff >> 16 is 0x0000 ffff or 0xffff ffff with signed arithmetic (should be 0xffff ffff which is probably not what you want
)...
your LGDT command seems weird to my sense ...
as far as i remember, the format is [b-a-s-e][l-m] : 4bytes of BASE address (check you give a ABSOLUTE address, not an offset from the data segment !) and then 2 bytes of limit (but maybe i should read the manual again ... )
any way, storing the limit in an long and then using ((char *)i) +2 to access it seems *really* hackish to me ... better declare a structure, imho/.
Re:GDT crash...
Posted: Thu Oct 31, 2002 10:47 am
by Zi
Thanks for your answer. But...
Hum... It doesn't work better... This is my new source... Are there any errors again !?
Code: Select all
/**
* Structure g?n?rale d'une GDT
**/
typedef struct s_entree_GDT
{
unsigned short limit15_00;
unsigned short base15_00;
unsigned char base23_16;
unsigned char type;
unsigned char type_util;
unsigned char base31_24;
} t_entree_gdt;
typedef struct s_gdtr
{
unsigned int base;
unsigned short limit;
} t_gdtr;
// La GDT peut avoir au plus 8192 segments...
//struct s_entree_GDT GDT[128];
t_entree_gdt GDT[128];
// Fonction permettant de charger la GDT (page 3-8)
void _lgdt(void * base, unsigned long limit)
{
unsigned long i[2];
/*i[0] = limit << 16;
i[1] = (unsigned long) base;*/
t_gdtr gdtr;
gdtr.base=(unsigned int) base;
gdtr.limit=(unsigned short) limit;
//__asm__ __volatile__ ("lgdt (%0)": :"p" (((char *) i)+2));
__asm__ __volatile__ ("lgdt (%0)": :"p" (gdtr));
print("GDT charg?e\n");
asm volatile("jmp reinit_cs\n \
reinit_cs:\n \
movl $0x10,%eax\n \
movw %ax,%ds\n \
movw %ax,%es\n \
movw %ax,%fs\n \
movw %ax,%gs\n \
movw %ax,%ss\n");
}
/**
* D?finit un descripteur de la GDT
**/
void set_gdt_desc(int num, unsigned long base, unsigned long limite, char G, char DB, char AVL,
char present, char DPL, char S, char t)
{
// CF page 3-10 du tome 3 du IA-32 Intel Architecture Software Developer's Manual.
GDT[num].limit15_00 = limite & 0xFFFF;
GDT[num].base15_00 = base & 0xFFFF;
GDT[num].base23_16 = (base >> 16) & 0xFF;
GDT[num].type = t & 0xF | ((present * 0x8 + DPL * 2 + S)<<8)&0xF0;
GDT[num].type_util = (limite >> 16) & 0xF + ((AVL + DB*4 + G*8)<<8)&0xF0;
GDT[num].base31_24 = (base >> 24) & 0xFF;
}
void init_gdt(void)
{
set_gdt_desc(0,0,0,0,0,0,0,0,0,0);
/* Le bouquin Intel est clair : le 1er descripteur
* doit ?tre enti?rement ? 0. D'o? cette ligne.
*/
set_gdt_desc(1,0,0xFFFFF,1,1,0,1,1,1,0xB); // CS
set_gdt_desc(2,0,0xFFFFF,1,1,0,1,1,1,0x7); // DS
_lgdt(GDT,0x3FF);
}
I can't see where is my mistake... Really... Please help me !!! If you want the full source of the OS, please, tell me !!!
Thanks.
Damien Szczyt
Re:GDT crash...
Posted: Thu Oct 31, 2002 1:00 pm
by algol
Could it be a alignement problem with your struct s_entree_GDT or is it packed ?
Re:GDT crash...
Posted: Thu Oct 31, 2002 1:23 pm
by Zi
I've changed the structs like this :
Code: Select all
typedef struct s_entree_GDT
{
unsigned short limit15_00;
unsigned short base15_00;
unsigned char base23_16;
unsigned char type;
unsigned char type_util;
unsigned char base31_24;
} t_entree_gdt __attribute__ ((packed));
typedef struct s_gdtr
{
unsigned short limit;
unsigned int base;
} t_gdtr __attribute__ ((packed));
and it doesn't work again...
hum... What again ?
Thanks.
Damien Szczyt
Re:GDT crash...
Posted: Thu Oct 31, 2002 5:53 pm
by algol
Here is a simpler init_gdt
Code: Select all
/**
* Structure g?n?rale d'une GDT
**/
// La GDT peut avoir au plus 8192 segments...
//struct s_entree_GDT GDT[128];
unsigned long int GDT[6] = { 0, 0, 0x0000FFFF, 0x00CF9A00, 0x0000FFFF, 0x00CF9200};
void init_gdt(void)
{
unsigned short int gdtr[4] = {23,GDT,((unsigned long int) GDT>>16),0};
__asm__ __volatile__ ("lgdt (%0)": :"p" (gdtr));
asm volatile(
"ljmp $0x08, $reinit_cs\n \
reinit_cs:\n \
movl $0x10,%eax\n \
movw %ax,%ds\n \
movw %ax,%es\n \
movw %ax,%fs\n \
movw %ax,%gs\n \
movw %ax,%ss\n \
");
printf("GDT charg?e\n");
}
En fait, j'ai un doute sur ta fa?on de recharger cs (un simple jump ??), c'est pourquoi en t?tonnant j'ai cherch? la syntaxe AT&T (j'utilise nasm) qui permet de faire un "far jump" et je l'ai essay? sur cet exemple simple. (En fait j'ai peu ? peu ?limin? tes fonctions)
Tu pourras ainsi au moins tester tes autres fonctions.
J'avoue ne pas avoir eu le courage de v?rifier set_gdt_desc ...
Re:GDT crash...
Posted: Fri Nov 01, 2002 4:06 am
by Zi
ok, ?a a l'air de marcher, merci beaucoup... J'ai plus qu'? refaire la fonction set_gdt_desc en l'appliquant ? ta structure. Merci beaucoup...
Damien Szczyt
Re:GDT crash...
Posted: Fri Nov 01, 2002 4:57 am
by Zi
Juste pour savoir... A quoi correspond le 23 dans la gdtr !?
Re:GDT crash...
Posted: Fri Nov 01, 2002 6:38 am
by Tim
Pouvez-vous ecrire en Anglais ici, s'il vous plait? Not everyone can read French here.
Re:GDT crash...
Posted: Fri Nov 01, 2002 6:45 am
by Zi
sorry, I just said that it worked, but I asked wat was the 23 in the gdtr. I think I've found... There are 3 descriptors in the gdt. The GDT is GDT[6]. So 1 descriptor is a long int [2]. The limit is : [number of descriptors]*8-1. If there are 3 descriptors : limit=3*8-1=6*4-1=23...
Now, the 0 is the problem... But it seems to be less important...
Thanks
Damien Szczyt
Re:GDT crash...
Posted: Fri Nov 01, 2002 8:23 am
by algol
Here is code for set_gdt_desc but I don't succed with
gdtr ...
Code: Select all
typedef struct s_entree_GDT
{
unsigned short limit15_00;
unsigned short base15_00;
unsigned char base23_16;
unsigned char type;
unsigned char type_util;
unsigned char base31_24;
} t_entree_gdt __attribute__ ((packed));
typedef struct s_gdtr
{
unsigned short int limit;
unsigned long int base;
} t_gdtr __attribute__ ((packed));
// La GDT peut avoir au plus 8192 segments...
t_entree_gdt GDT[128];
// Fonction permettant de charger la GDT (page 3-8)
void _lgdt(unsigned long int base, unsigned short int limit)
{
t_gdtr gdtr;
gdtr.limit=(unsigned short int) limit;
gdtr.base=(unsigned long int) base;
unsigned short int gdtr2[3] = {limit,(unsigned long int)base&0xffff,((unsigned long int) base>>16)};
__asm__ __volatile__ ("lgdt (%0)": :"p" (gdtr2));
printf("GDT charg?e\n");
asm volatile(
"ljmp $0x08, $reinit_cs\n \
reinit_cs:\n \
movl $0x10,%eax\n \
movw %ax,%ds\n \
movw %ax,%es\n \
movw %ax,%fs\n \
movw %ax,%gs\n \
movw %ax,%ss\n");
}
/**
* D?finit un descripteur de la GDT
**/
void set_gdt_desc
(int num, unsigned long base, unsigned long limite, char G, char DB, char AVL, char present, char DPL, char S, char t)
{
// CF page 3-10 du tome 3 du IA-32 Intel Architecture Software Developer's Manual.
GDT[num].limit15_00 = limite & 0xFFFF;
GDT[num].base15_00 = base & 0xFFFF;
GDT[num].base23_16 = (base >> 16) & 0xFF;
GDT[num].base31_24 = (base >> 24) & 0xFF;
GDT[num].type_util =( (limite >> 16) & 0x0F) + ( ((AVL + DB*4 + G*8)<<4)&0xF0);
GDT[num].type = (t & 0x0F) + (((present * 0x8 + DPL * 2 + S)<<4)&0xF0);
}
void init_gdt(void)
{
set_gdt_desc(0,0,0,0,0,0,0,0,0,0);
/* Le bouquin Intel est clair : le 1er descripteur
* doit ?tre enti?rement ? 0. D'o? cette ligne.
*/
//(int num, unsigned long base, unsigned long limite, char G, char DB, char AVL, char present, char DPL, char S, char t)
set_gdt_desc(1,0, 0xFFFFF, 1, 1, 0, 1, 0, 1, 0xB ); // CS
set_gdt_desc(2,0, 0xFFFFF, 1, 1, 0, 1, 0, 1, 0x2); // DS
_lgdt((unsigned long int )GDT,0x3FF);
}
23 is the actual limit of GDT 3*8-1
Re:GDT crash...
Posted: Fri Nov 01, 2002 8:31 am
by Zi
ok, thanks, but I think i'll use your method... I'm writing an another set_gdt_desc.
But what's the 0 in the gdtr !?
unsigned short int gdtr[4] = {23,GDT,((unsigned long int) GDT>>16),0};
Thanks.
Damien Szczyt
Re:GDT crash...
Posted: Fri Nov 01, 2002 8:53 am
by algol
0 was just for padding, you don't need it at all.
set_gdt_desc code is yours. I just corrected it.