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.