Page 1 of 1

GDT and IDT problems

Posted: Fri Oct 15, 2004 3:44 am
by ManOfSteel
Hello,
I'm currently switching from a three-staged OS to a two-staged one. I made this piece of code yesterday and I'm having some troubles with it.
Now everytime I try to add a new segment descriptor (a video segment, a call gate, ...) in the init file, I get an error. The error occurs when I move the address of the newly created video descriptor in gs for example. Why? Isn't possible to add a new segment descriptor to an existing GDT?
Also, what is the problem with the IDT, everytime I try 'int 0' I get an error.
Thank you in advance.


Boot file:

Code: Select all

[bits 16]
[org 0x7c00]

jmp boot
GDTR:
GDTsize dw GDTEND-GDT-1
GDTbase dd 0x500


GDT:
NULLSEL EQU $-GDT
dd 0
dd 0
CODESEL EQU $-GDT
dw 0xFFFF
dw 0
db 0
db 0x9A
db 0xCF
db 0
DATASEL EQU $-GDT
dw 0xFFFF
dw 0
db 0
db 0x92
db 0xCF
db 0
GDTEND:

boot:
mov ax,cs
mov ds,ax
mov es,ax
mov fs,ax
mov ax,0x200
mov ss,ax
mov sp,0x1000

read:
mov ax,900h
mov es,ax
xor bx,bx
mov ah,2
mov al,3
xor ch,ch
mov cl,2
xor dx,dx
int 13h
jc read

mov dx,0x3F2
mov al,0x0C
out dx,al

xor ax,ax
mov ds,ax
mov es,ax
mov si,GDT
mov di,[GDTbase]
mov cx,[GDTsize]
cld
rep movsb

cli
mov eax,cr0
or al,1
mov cr0,eax

lgdt [GDTR]

jmp CODESEL:FLUSH
[bits 32]

FLUSH:
mov eax,DATASEL
mov ds,eax
mov es,eax
mov fs,eax
mov gs,eax
mov ss,eax
mov esp,0xffff

jmp dword 8h:9000h

TIMES 510-($-$$) db 0
DW 0xAA55

Init file:

Code: Select all

[bits 32]
[org 9000h]

mov ebx,Int01Handler
mov [entry00],bx
shr ebx,16
mov [entry00+6],bx

mov si,GDT
mov di,[GDTbase]
mov cx,[GDTsize]
cld
rep movsb

mov si,IDT
mov di,[IDTbase]
mov cx,[IDTsize]
cld
rep movsb

lidt [IDTR]
lgdt [GDTR]

mov eax,DATASEL
mov ds,eax
mov es,eax
mov fs,eax
mov eax,VIDEOSEL ;<+++ NOT WORKING
mov gs,eax
mov eax,DATASEL
mov ss,eax
mov esp,0xffff

;mov ecx,4 ;<+++ these were working before I changed the GDT
;mov edi,0b8000h
;mov esi,string
;rep movsw

int 0
jmp $

Int01Handler:
jmp $
iret

string db 't e s t ',0

GDTR:
GDTsize dw GDTEND-GDT-1
GDTbase dd 0x500

GDT:
NULLSEL EQU $-GDT
dd 0
dd 0
CODESEL EQU $-GDT
dw 0xFFFF
dw 0
db 0
db 0x9A
db 0xCF
db 0
DATASEL EQU $-GDT
dw 0xFFFF
dw 0
db 0
db 0x92
db 0xCF
db 0
VIDEOSEL EQU $-GDT ;
db 9fh
db 0fh
db 0
db 80h
db 0bh
db 10010010b
db 0
db 0
GDTEND:

IDTR:
IDTsize dw IDTEND-IDT-1
IDTbase dd 0x600

IDT:
entry00:
dw 0
dw 8h
db 0
db 10001110b
dw 0
IDTEND:

Re:GDT and IDT problems

Posted: Fri Oct 15, 2004 3:51 am
by Candy
ManOfSteel wrote: Now everytime I try to add a new segment descriptor (a video segment, a call gate, ...) in the init file, I get an error. The error occurs when I move the address of the newly created video descriptor in gs for example. Why? Isn't possible to add a new segment descriptor to an existing GDT?
When adding the GDT entry, do you raise the limit too? Otherwise, that is a good reason why you can't reach it.

Re:GDT and IDT problems

Posted: Fri Oct 15, 2004 4:47 am
by ManOfSteel
When adding the GDT entry, do you raise the limit too? Otherwise, that is a good reason why you can't reach it.
The limit is automatically raised (GDTsize dw GDTEND-GDT-1).

Re:GDT and IDT problems

Posted: Fri Oct 15, 2004 5:38 am
by Brendan
Hi,

Code: Select all

mov si,GDT
mov di,[GDTbase]
mov cx,[GDTsize]
cld
rep movsb

mov si,IDT
mov di,[IDTbase]
mov cx,[IDTsize]
cld
rep movsb
In your boot file and your init file you're using loops (like above) to copy GDT/IDT entries. With all 3 of these loops you do not copy the last byte, because [IDTsize] and [GDTsize] are actually "size-1".

To fix it do something like:

Code: Select all

mov si,GDT
mov di,[GDTbase]
mov cx,[GDTsize]
cld
rep movsb
movsb
Or (even faster):

Code: Select all

mov si,GDT
mov di,[GDTbase]
mov cx,(GDTEND-GDT)/4
cld
rep movsd

The last bytes would be the highest 8 bits of the video descriptor's base address for both GDT's, and the highest 8 bits of the offset for the IDT entry.

Also your stack should be aligned to a 4 byte boundary - use "mov esp,0xfffc" instead of "mov esp,0xffff".

Because the "push" instruction actually does something like "dec esp;mov [esp],<data>", you can use "mov esp,0x10000"...


Cheers,

Brendan

Re:GDT and IDT problems

Posted: Fri Oct 15, 2004 5:40 am
by Pype.Clicker
kinda weird ... do you have more infos about why it doesn't like it
(e.g. register values, error code, bochs panic messages, etc ?)

Re:GDT and IDT problems

Posted: Fri Oct 15, 2004 4:38 pm
by ManOfSteel
It's working better for now.
Thanks everybody for your time and your help.

Re:GDT and IDT problems

Posted: Sat Oct 16, 2004 8:49 am
by ManOfSteel
Does someone know about any bug causing a triple fault in Bochs, because the troubles I had yesterday with the IDT were only "seen" by Bochs while on a real computer, everything worked fine?
And if not, do you know any other emulator I could use on Windows?
I tried the OS image on Bochs 1.4.1 and 2.1 and both didn't work.
Thanks in advance.

Re:GDT and IDT problems

Posted: Sun Oct 17, 2004 9:04 am
by Pype.Clicker
there are several differences between Bochs and a real system X. Those differences mainly causes faults on real systems than on bochs ...

A possible cause, if your IDT is set in the bootsector, would be that you assume CS:IP=0000:7C00 and that you get 07c0:0000 instead ... i suggest you get a look at http://www.osdev.org/osfaq2/index.php/H ... %20working.

There are of course other emulators (check the FAQ), for instance VMWARE, but BOCHS is the best one for bug-tracking, afaik.