Page 1 of 1

"Segment not present" on some machines

Posted: Sat Jun 02, 2007 5:40 pm
by raistlinthewiz
Hi, i do have a basic GDT code working nice on my test enviroment like bochs, qemu and vmware. The code & kernel just runs fine. Also on my laptop with 1GB ram, it just run well too. But when i try the kernel on my desktop system with 2GB ram, i do just get segment not present exception.

My current GDT code:

Code: Select all

#include "include/gdt.h"

void set_gdt_entry(int num, unsigned long base,unsigned long limit, unsigned char access, unsigned char gran)
{
  gdt[num].base=(base & 0xFFFF); /* lowest 2 bytes of base */
  gdt[num].base_middle=(base >> 16) & 0xFF; /* third third byte */
  gdt[num].base_high=(base >> 24 ) & 0xFF; /* highest byte */
  
  gdt[num].limit=(limit & 0xFFFF); /* lowest 2 bytes of limit */
  
  gdt[num].granularity=((limit >> 16) & 0x0F); /* 1 byte */
  gdt[num].granularity|=(gran & 0xF0); /* 1 byte */
  gdt[num].access=access;

}

  gp.base=(unsigned int)&gdt; /* set base address to our descriptor table */
  gp.limit=(sizeof(struct gdt_entry) * 3)-1; /* (size of our gdt table)-1  */
  
  /* NULL descriptor table - CPU needs it */
  set_gdt_entry(0,0,0,0,0);

set_gdt_entry(1,0x0,0xFFFFF,0x9A,0xC0);
set_gdt_entry(2,0x0,0xFFFFF,0x92,0xC0);
  gdt_flush(); 
anyone hit this problem before?

thanks

Posted: Sun Jun 03, 2007 2:28 pm
by Combuster
I tend to look somehwere else, like wether or not you zero memory before using it.

Posted: Mon Jun 04, 2007 2:02 am
by mathematician
What does gdt_flush() do? If I read the Intel manual aright, a segment not present fault can only occur when you are either loading a segment register (as in an int or far call, or explicitly) or else accessing one of the control registers.

Posted: Mon Jun 04, 2007 2:17 am
by pcmattman
I can show you the code:

Code: Select all

gdt_flush
    lgdt _gp
    jmp 0x08:flush
flush:
    mov ax,0x10
    mov ds,ax
    mov es,ax
    mov fs,ax
    mov gs,ax
    ret
In set_gdt_entry, 0xC0 should be 0xCF.