flat assembler
Message board for the users of flat assembler.

Index > OS Construction > Strange problem with LGDT

Author
Thread Post new topic Reply to topic
Marvin



Joined: 20 Mar 2007
Posts: 6
Location: Germany
Marvin 08 Aug 2007, 08:41
Hi,
I have a (in my opinion) very strange problem with LGDT. My kernel is loaded to 0x1000:0x0000 in real mode (with the FAT12-Bootloader by John S. Fine). Then it enables the 800x600x32 VESA mode and tries to switch to protected mode. But when I'm loading the GDT, my computer and bochs hang. Other VMs like VirtualBox, QEMU, VMware or VirtualPC work!

This is the first stuff in my kernel.asm:
Code:
use16
;disable interrupts
cli

;update the segment registers
mov   ax,cs
mov   ds,ax
mov   es,ax

;enable A20
.5:
in    al,0x64
test  al,2
jnz   .5
mov   al,0xD1
out   0x64,al
.6:
in    al,0x64
and       ax,2
jnz     .6
mov   al,0xDF
out   0x60,al

;check if vesa is supported
mov   ax,0x4F00
mov   di,VBEInfoBlock - 0x10000
int 0x10

;check if function is supported
cmp   al,0x4F
je    ctrl_else0_1
mov   si,vbe_chosen_func_not_supported
mov   ax,0xB000
mov   es,ax
mov   di,0x8000
mov   al,1
ctrl_while1_1:
or    al,al
je    ctrl_wend1_1
lodsb
or    al,al
je    ctrl_else2_1
stosb
mov   al,7
stosb
ctrl_else2_1:
ctrl_endif2_1:
jmp   ctrl_while1_1
ctrl_wend1_1:
jmp   no_vesa
ctrl_else0_1:
ctrl_endif0_1:

;select ah, check if function call was successful

;case 1: wasn't successful
case1_0:
cmp   ah,1
jne   case1_1
mov   si,vbe_func_call_error
mov   ax,0xB000
mov   es,ax
mov   di,0x8000
mov   al,1
ctrl_while2_1:
or    al,al
je    ctrl_wend2_1
lodsb
or    al,al
je    ctrl_else3_1
stosb
mov   al,7
stosb
ctrl_else3_1:
ctrl_endif3_1:
jmp   ctrl_while2_1
ctrl_wend2_1:
jmp   no_vesa
jmp   endselect1

;case 2: function isn't supported by hardware
case1_1:
cmp   ah,2
jne   case1_2
mov   si,vbe_chosen_func_not_supported_by_hw
mov   ax,0xB000
mov   es,ax
mov   di,0x8000
mov   al,1
ctrl_while2_2:
or    al,al
je    ctrl_wend2_2
lodsb
or    al,al
je    ctrl_else3_2
stosb
mov   al,7
stosb
ctrl_else3_2:
ctrl_endif3_2:
jmp   ctrl_while2_2
ctrl_wend2_2:
jmp   no_vesa
jmp   endselect1

;case 3: function mustn't be called now
case1_2:
cmp   ah,3
jne   case1_3
mov   si,vbe_func_mustnt_be_called
mov   ax,0xB000
mov   es,ax
mov   di,0x8000
mov   al,1
ctrl_while2_3:
or    al,al
je    ctrl_wend2_3
lodsb
or    al,al
je    ctrl_else3_3
stosb
mov   al,7
stosb
ctrl_else3_3:
ctrl_endif3_3:
jmp   ctrl_while2_3
ctrl_wend2_3:
jmp   no_vesa
case1_3:
endselect1:

;check if the new signature is "VESA", if not vesa isn't supported
mov   si,VbeSignature - 0x10000
lodsd
cmp   eax,0x41534556
je    ctrl_else0_2
mov   di,answer
stosd
mov   si,func_not_supported
mov   ax,0xB000
mov   es,ax
mov   di,0x8000
mov   al,1
ctrl_while1_2:
or    al,al
je    ctrl_wend1_2
lodsb
or    al,al
je    ctrl_else2_2
stosb
mov   al,7
stosb
ctrl_else2_2:
ctrl_endif2_2:
jmp   ctrl_while1_2
ctrl_wend1_2:
jmp   no_vesa
ctrl_else0_2:
ctrl_endif0_2:

;get informations about mode 0x115 (should be 800x600x32)
mov   ax,0x4F01
mov   di,VbeModeInfoBlock - 0x10000
mov   cx,0x115
int 0x10

;check if function is supported
cmp   al,0x4F
je    ctrl_else0_3
mov   si,vbe_chosen_func_not_supported
mov   ax,0xB000
mov   es,ax
mov   di,0x8000
mov   al,1
ctrl_while1_3:
or    al,al
je    ctrl_wend1_3
lodsb
or    al,al
je    ctrl_else2_3
stosb
mov   al,7
stosb
ctrl_else2_3:
ctrl_endif2_3:
jmp   ctrl_while1_3
ctrl_wend1_3:
jmp   no_vesa
ctrl_else0_3:
ctrl_endif0_3:

;select ah, check if function call was successful

;case 1: wasn't successful
case2_0:
cmp   ah,1
jne   case2_1
mov   si,vbe_func_call_error
mov   ax,0xB000
mov   es,ax
mov   di,0x8000
mov   al,1
ctrl_while2_4:
or    al,al
je    ctrl_wend2_4
lodsb
or    al,al
je    ctrl_else3_4
stosb
mov   al,7
stosb
ctrl_else3_4:
ctrl_endif3_4:
jmp   ctrl_while2_4
ctrl_wend2_4:
jmp   no_vesa
jmp   endselect2

;case 2: function isn't supported by hardware
case2_1:
cmp   ah,2
jne   case2_2
mov   si,vbe_chosen_func_not_supported_by_hw
mov   ax,0xB000
mov   es,ax
mov   di,0x8000
mov   al,1
ctrl_while2_5:
or    al,al
je    ctrl_wend2_5
lodsb
or    al,al
je    ctrl_else3_5
stosb
mov   al,7
stosb
ctrl_else3_5:
ctrl_endif3_5:
jmp   ctrl_while2_5
ctrl_wend2_5:
jmp   no_vesa
jmp   endselect2

;case 3: function mustn't be called now
case2_2:
cmp   ah,3
jne   case2_3
mov   si,vbe_func_mustnt_be_called
mov   ax,0xB000
mov   es,ax
mov   di,0x8000
mov   al,1
ctrl_while2_6:
or    al,al
je    ctrl_wend2_6
lodsb
or    al,al
je    ctrl_else3_6
stosb
mov   al,7
stosb
ctrl_else3_6:
ctrl_endif3_6:
jmp   ctrl_while2_6
ctrl_wend2_6:
jmp   no_vesa
case2_3:
endselect2:

;VESA and mode 800x600x32 are supported
mov   si,vesa_supported
mov   ax,0xB000
mov   es,ax
mov   di,0x8000
mov   al,1
ctrl_while0_1:
or    al,al
je    ctrl_wend0_1
lodsb
or    al,al
je    ctrl_else1_1
stosb
mov   al,7
stosb
ctrl_else1_1:
ctrl_endif1_1:
jmp   ctrl_while0_1
ctrl_wend0_1:

;Enable 800x600x32 with linear frame buffer
mov   ax,0x4F02
mov   bx,0x4115
int 0x10

;Say the PM code, that VESA is on
mov   [IsVESA - 0x10000],1

no_vesa:

;switch to PM

;fill the segment registers with 0 (else they won't select the dummy descriptor and there'll be a GPF)
xor   ax,ax
mov   ds,ax
mov   es,ax
mov   ss,ax
mov   fs,ax
mov   gs,ax
xor   esp,esp

;Trying to load the GDT
lgdt [gdt_desc]
;This point here will never be executed! The program is frozen here.

;If the program would continue, it would enter the PM here.
mov   eax,cr0
or    eax,1
mov   cr0,eax

;Flush the pipeline and use 32 bit commands
jmp   far 0x28:pmode
;The selected descriptor has the following attributes:
;Base is on 0x10000
;Size is 0xFFFEF * 4KB
;It's a readable code segment with DPL = 0
;It's for 80386+

use32

pmode:

;Fill the segment registers with the correct values
mov   ax,0x10
mov   ds,ax
mov   es,ax
mov   ss,ax
;The selected descriptor has the following attributes:
;Base is on 0x0000
;Size is 0xFFFFF * 4KB
;It's a writeable data segment with DPL = 0
;It's for 80386+

xor   ax,ax
mov   fs,ax
mov   gs,ax

mov   esp,0x1FFFFF

jmp   far 0x08:start
;The selected descriptor has the following attributes:
;Base is on 0x0000
;Size is 0xFFFFF * 4KB
;It's a readable code segment with DPL = 0
;It's for 80386+

func_not_supported db "VESA functions aren't supported., answer is "
answer db 0,0,0,0,0
vbe_chosen_func_not_supported db "The chosen VBE function isn't supported.",0
vbe_chosen_func_not_supported_by_hw db "The chosen VBE function isn't supported by hardware.",0
vesa_supported db "VESA 800x600x32 is supported.",0
vbe_func_call_error db "The function call wasn't successful.",0
vbe_func_mustnt_be_called db "The function mustn't be called.",0
vbe_invalid_video_mode db "Invalid video mode.",0

org 0x10000+$

;Here is the GDT
gdt_start:
gdt_entry_dummy: ;Index 0 [selector = 0x00]
dd 0, 0
gdt_entry_sys_code: ;Index 1 [selector = 0x08]
dw 0xFFFF
dw 0x0000
db 0x00
db 10011010b
db 11001111b
db 0x00
;Code executable/readable, DPL = 0, Base = 0x00000000, Size = 0xFFFFF * 4KB, 80386

gdt_entry_sys_data: ;Index 2 [selector = 0x10]
dw 0xFFFF
dw 0x0000
db 0x00
db 10010010b
db 11001111b
db 0x00
;Data readable/writeable, DPL = 0, Base = 0x00000000, Size = 0xFFFFF * 4KB, 80386

gdt_entry_sys_video: ;Index 3 [selector = 0x18]
dw 0xFA00
dw 0x0000
db 0x0A
db 10110010b
db 01000000b
db 0x00
;Data readable/writeable, DPL = 1, Base = 0x000A0000, Size = 0xFA00 * 1B, 80386
;This descriptor was used for VGA mode 0x13

gdt_entry_sys_text: ;Index 4 [selector = 0x20]
dw 0x8000
dw 0x8000
db 0x0B
db 10010010b
db 01000000b
db 0x00
;Data readable/writeable, DPL = 0, Base = 0x000B8000, Size = 0x8000 * 1B, 80386

gdt_entry_sys_scode: ;Index 5 [selector = 0x28]
dw 0xFFEF
dw 0x0000
db 0x01
db 10011010b
db 11001111b
db 0x00
;Code executable/readable, DPL = 0, Base = 0x00010000, Size = 0xFFFEF * 4KB, 80386

gdt_entry_sys_sdata: ;Index 6 [selector = 0x30]
dw 0x1000
dw 0x0000
db 0x01
db 10010010b
db 11000000b
db 0x10
;Data readable/writeable, DPL = 0, Base = 0x00010000, Size = 0xFFFEF * 4KB, 80386

gdt_end:

gdt_desc:
dw gdt_end - gdt_start - 1
dd gdt_start
dw 0 ;Don't know why this could be important, but somewhere you're able to see that

VBEInfoBlock:
VbeSignature db "VBE2"
VbeVersion dw 0
VbeOEMStringPtr dd 0
VbeCapabilities dd 0
VbeVideoModePtr dd 0
VbeTotalMemory dw 0
VbeOEMSoftwareRev dw 0
VbeOEMVendorNamePtr dd 0
VbeOEMProductNamePtr dd 0
VbeOEMProductRevPtr dd 0
VbeReserver  db 222 DUP(0)
VbeOEMData  db 256 DUP(0)

VbeModeInfoBlock:
VbeModeModeAttributes dw 0
VbeModeWinAAttributes db 0
VbeModeWinBAttributes db 0
VbeModeWinGranularity dw 0
VbeModeWinSize dw 0
VbeModeWinASegment dw 0
VbeModeWinBSegment dw 0
VbeModeWinFuncPtr dd 0
VbeModeBytesPerScanLine dw 0
VbeModeXResolution dw 0
VbeModeYResolution dw 0
VbeModeXCharSize db 0
VbeModeYCharSize db 0
VbeModeNumberOfPlanes db 0
VbeModeBitsPerPixel db 0
VbeModeNumberOfBanks db 0
VbeModeMemoryModel db 0
VbeModeBankSize db 0
VbeModeNumOfImagePages db 0
VbeModeReserved_page db 0
VbeModeRedMaskSize db 0
VbeModeRedMaskPos db 0
VbeModeGreenMaskSize db 0
VbeModeGreenMaskPos db 0
VbeModeBlueMaskSize db 0
VbeModeBlueMaskPos db 0
VbeModeReservedMaskSize db 0
VbeModeReservedMaskPos db 0
VbeModeDirColorModeInfo db 0
VbeModePhysBasePtr dd 0
VbeModeOffScreenMemOffs dd 0
VbeModeOffScreenMemSize dw 0
VbeModeLinByPerScanLine dw 0
VbeModeBnkNumberOfPages db 0
VbeModeLinNumberOfPages db 0
VbeModeLinRedMaskSize db 0
VbeModeLinRedFieldPos db 0
VbeModeLinGreenMaskSize db 0
VbeModeLinGreenFieldPos db 0
VbeModeLinBlueMaskSize db 0
VbeModeLinBlueFieldPos db 0
VbeModeLinRsvdMaskSize db 0
VbeModeLinRsvdFieldPos db 0
VbeModeMaxPixelClock dd 0
VbeModeReserved  db 190 DUP(0)

IsVESA db 0

start:

;Here follows other system code    


Bochs debug:
Code:
00000450000i[WGUI ] dimension update x=720 y=400 fontheight=16 fontwidth=9 bpp=8
00000695508e[HD   ] device set to 0 which does not exist
00000695801e[HD   ] device set to 1 which does not exist
00000802818i[CLVGA] VBE set bpp (24)
00000802840i[CLVGA] VBE set xres (800)
00000802921i[CLVGA] VBE set yres (600)
00000802959i[CLVGA] VBE enabling x 800, y 600, bpp 24, 1440000 bytes visible
00000802959i[WGUI ] dimension update x=800 y=600 fontheight=0 fontwidth=0 bpp=24
00003303000p[WGUI ] >>PANIC<< POWER button turned off.
00003303000i[SYS  ] Last time is 1186562163
00003303000i[CPU0 ] real mode
00003303000i[CPU0 ] CS.d_b = 16 bit
00003303000i[CPU0 ] SS.d_b = 16 bit
00003303000i[CPU0 ] | EAX=41530000  EBX=00004115  ECX=000a0115  EDX=00000000
00003303000i[CPU0 ] | ESP=00000000  EBP=00007c00  ESI=0000029c  EDI=0000803a
00003303000i[CPU0 ] | IOPL=0 NV UP DI PL ZR NA PE NC
00003303000i[CPU0 ] | SEG selector     base    limit G D
00003303000i[CPU0 ] | SEG sltr(index|ti|rpl)     base    limit G D
00003303000i[CPU0 ] |  CS:1000( 0000| 0|  0) 00010000 0000ffff 0 0
00003303000i[CPU0 ] |  DS:0000( 0000| 0|  0) 00000000 0000ffff 0 0
00003303000i[CPU0 ] |  SS:0000( 0000| 0|  0) 00000000 0000ffff 0 0
00003303000i[CPU0 ] |  ES:0000( 0000| 0|  0) 00000000 0000ffff 0 0
00003303000i[CPU0 ] |  FS:0000( 0000| 0|  0) 00000000 0000ffff 0 0
00003303000i[CPU0 ] |  GS:0000( 0000| 0|  0) 00000000 0000ffff 0 0
00003303000i[CPU0 ] | EIP=000001bb (000001bb)
00003303000i[CPU0 ] | CR0=0x00000010 CR1=0 CR2=0x00000000
00003303000i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
00003303000i[     ] restoring default signal behavior
00003303000i[CTRL ] quit_sim called with exit code 1    


You can see that the kernel enables VESA. But then it hangs and you have to click on the power button. EIP is on 0x01BB, there's the lgdt command.
Is somebody there, who could help me?

P.S.: There's another little question... What segments are FS and GS?


Last edited by Marvin on 08 Aug 2007, 10:38; edited 1 time in total
Post 08 Aug 2007, 08:41
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
DOS386



Joined: 08 Dec 2006
Posts: 1905
DOS386 08 Aug 2007, 08:52
Do CLI after VESA stuff ?

_________________
Bug Nr.: 12345

Title: Hello World program compiles to 100 KB !!!

Status: Closed: NOT a Bug
Post 08 Aug 2007, 08:52
View user's profile Send private message Reply with quote
Marvin



Joined: 20 Mar 2007
Posts: 6
Location: Germany
Marvin 08 Aug 2007, 09:34
Oh... Embarassed
Yeah, but VESA initialization works fine WITH cli and when I put it after that my code also doesn't work...
Post 08 Aug 2007, 09:34
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
Octavio



Joined: 21 Jun 2003
Posts: 366
Location: Spain
Octavio 08 Aug 2007, 10:26
LGDT acces to data above the 64k limit (program is in real mode)
causing a GPF, you need a better design.
Post 08 Aug 2007, 10:26
View user's profile Send private message Visit poster's website Reply with quote
Marvin



Joined: 20 Mar 2007
Posts: 6
Location: Germany
Marvin 08 Aug 2007, 10:38
I thought that would be allowed because LGDT uses a 32bit address... Thank you, I'll try this! Wink
Post 08 Aug 2007, 10:38
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
DOS386



Joined: 08 Dec 2006
Posts: 1905
DOS386 08 Aug 2007, 12:23
> Other VMs like VirtualBox, QEMU, VMware or VirtualPC work!

QEMU is known to neglect (intentionally) some checks like segment limit Shocked

VPC ... yeah Crying or Very sad

> Do CLI after VESA stuff ?

Bad guess Sad

> 00003303000p[WGUI ] >>PANIC<< POWER button turned off.

BOCHS is supposed to be the most correct emulator Idea ... but it has a serious "EIP=0" bug in 2.3 and some additional relevant bugs in 2.2.6 Neutral

_________________
Bug Nr.: 12345

Title: Hello World program compiles to 100 KB !!!

Status: Closed: NOT a Bug
Post 08 Aug 2007, 12:23
View user's profile Send private message Reply with quote
f0dder



Joined: 19 Feb 2004
Posts: 3175
Location: Denmark
f0dder 09 Aug 2007, 10:53
IMHO you shouldn't bother with enabling graphics mode until you have your basics up and working correctly. Otherwise you'll end up with another of those "look ma, I can plot a pixel from my ring0 bootsector!", and that'll basically be it.

If you really want to do something, do some kernel work and get that up and running (textmode is easier to debug, and you won't be debugging kernel and graphics routines at the same time that way) before you bother with graphics.
Post 09 Aug 2007, 10:53
View user's profile Send private message Visit poster's website Reply with quote
Marvin



Joined: 20 Mar 2007
Posts: 6
Location: Germany
Marvin 09 Aug 2007, 13:21
@Octavio:
Thank you! That was it. I copy my GDT now to an address smaller than 0x10000 and everything's good. Smile

@NTOSKRNL_VXE:
>> QEMU is known to neglect (intentionally) some checks like segment limit

I thought something like that, but I also thought that VMware would check many things...

>> VPC ... yeah

Laughing

@f0dder:
You're right but of course this isn't my whole kernel. And I work on my OS for a year now. For the debugging: I wrote a procedure that's able to print text on the screen for graphics mode...
My whole kernel.bin has a size of exactly 100 KB (without filling up space with zeros). Wink
Post 09 Aug 2007, 13:21
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
f0dder



Joined: 19 Feb 2004
Posts: 3175
Location: Denmark
f0dder 09 Aug 2007, 13:49
Marvin: heh, okay - I just thought you were in initial development since you want to do VESA so early. Personally I'd postpone VESA init until a V86 monitor had been implemented :]
Post 09 Aug 2007, 13:49
View user's profile Send private message Visit poster's website Reply with quote
Marvin



Joined: 20 Mar 2007
Posts: 6
Location: Germany
Marvin 10 Aug 2007, 07:50
Oh, now I have to tell you about my "ignorance": I don't know how to implement a V86 so I init VESA at the beginning of my kernel... Embarassed
Post 10 Aug 2007, 07:50
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
f0dder



Joined: 19 Feb 2004
Posts: 3175
Location: Denmark
f0dder 10 Aug 2007, 10:50
Don't feel ignorant, implementing a V86 monitor is one of the a bit less trivial tasks - I never got around to it in my own toy kernel, which I haven't really touched since 2002 Smile

But I recall that there's source code available somewhere for V86, and the documentation these days is better than 10 years ago Razz
Post 10 Aug 2007, 10:50
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.