Page 1 of 2

Problem with far jump ptr16:32 and data descriptor in GDT

Posted: Tue Jan 05, 2016 9:35 am
by startrail
I am trying to write my own bootloader.
But I am stuck at the far jump after setting the bit 0 of cr0 register.

During the assembling by nasm I get the following warning:

Code: Select all

bootloader.asm:182: warning: word data exceeds bounds

Code: Select all

call setup_basic_gdt

mov ax,0x10
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov ss,ax
cli
mov eax,cr0
or eax,1
mov cr0,eax
mov eax,0xDEADBEEF
;jmp 0x8:0x00010000    ;Doesn't work (this is the place where I get the warning)
db 0x66        ;Current workaround
db 0xea
dd 0x00010000
dw 0x0008
The code to which I jump to sets the eax to 0xCAFEBABE and is working fine with the workaround
How do I get NASM to emit the opcode for far jump of type ptr16:32

Also when I see the logs after exiting the VM (VirtualBox), the base of data descriptor appears to be 0x100 and limit is 0xffff whereas the expected value is base=0x00 and limit=0xfffff

Code: Select all

00:00:14.138038 ****************** Guest state at power off ******************
00:00:14.138041 Guest CPUM (VCPU 0) state: 
00:00:14.138044 eax=cafebabe ebx=00000000 ecx=00040000 edx=534d4150 esi=00000203 edi=00000000
00:00:14.138046 eip=00010006 esp=00000c00 ebp=00000006 iopl=0         nv up di pl zr na po nc
00:00:14.138047 cs={0008 base=0000000000000000 limit=000fffff flags=0000409b} dr0=00000000 dr1=00000000
00:00:14.138049 ds={0010 base=0000000000000100 limit=0000ffff flags=00000093} dr2=00000000 dr3=00000000
00:00:14.138050 es={0010 base=0000000000000100 limit=0000ffff flags=00000093} dr4=00000000 dr5=00000000
00:00:14.138051 fs={0010 base=0000000000000100 limit=0000ffff flags=00000093} dr6=ffff0ff0 dr7=00000400
00:00:14.138052 gs={0010 base=0000000000000100 limit=0000ffff flags=00000093} cr0=00000011 cr2=00000000
00:00:14.138053 ss={0010 base=0000000000000100 limit=0000ffff flags=00000093} cr3=00000000 cr4=00000000
00:00:14.138054 gdtr=000000000000804c:001f  idtr=0000000000000000:ffff  eflags=00000006
00:00:14.138055 ldtr={0000 base=00000000 limit=0000ffff flags=00000082}
00:00:14.138056 tr  ={0000 base=00000000 limit=0000ffff flags=0000008b}
Here is my current GDT

Code: Select all

basic_GDT_table:
	null_descriptor dq 0
	code_segment:
		cs_lim dw 0xffff
		cs_base dw 0x0000
		cs_base_high db 0x00
		cs_access db 10011010b     ;type 0x9a
		cs_lim_high_flags db 0x4f
		cs_base_highest db 0x00
	data_segment:
		ds_lim dw 0xffff
		ds_base dw 0x0000
		ds_base_high db 0x00
		ds_access db 10010010b     ;type 0x92
		ds_lim_high_flags db 0x4f
		ds_base_highest db 0x00
	tss_segment dq 0

Re: Problem with far jump ptr16:32 and data descriptor in GD

Posted: Tue Jan 05, 2016 9:56 am
by Combuster
Did you try "jmp dword" ?

Re: Problem with far jump ptr16:32 and data descriptor in GD

Posted: Tue Jan 05, 2016 10:02 am
by startrail
Yes that worked with

Code: Select all

jmp dword 0x0008:0x00010000
But what about the data descriptor? I still can't figure it out.
Thank you for the help

Re: Problem with far jump ptr16:32 and data descriptor in GD

Posted: Tue Jan 05, 2016 10:03 am
by TightCoderEx
You haven't loaded your descriptor table

Code: Select all

	lgdt [basic_GDT_table]
	mov  eax, cr0
	or   al, 1
	mov  cr0, eax

Re: Problem with far jump ptr16:32 and data descriptor in GD

Posted: Tue Jan 05, 2016 10:08 am
by startrail
I load the GDT by calling a routine before making the jump. And as I said, the code to which I jump works just fine. But the observed values of base and limit differ from the expected values, which is bugging me. Maybe I am making some mistakes while initializing the bit fields in the GDT.

Re: Problem with far jump ptr16:32 and data descriptor in GD

Posted: Tue Jan 05, 2016 11:11 am
by TightCoderEx
SZ should probably be 1 for 32 bit protected mode so both instances of 4F in GDT should be CF.

Re: Problem with far jump ptr16:32 and data descriptor in GD

Posted: Tue Jan 05, 2016 12:04 pm
by ggodw000
i see all the registers that you loaded with 2nd (3rd from start) descriptor has a base 0x100 but not code segment. but your flat flat data segment looks ok, could it be possibly something has modified the base bytes somewhere? how about you load code just in case to see what happens?
If you see it on VM, try it on another machine to see if it happens. That should give an idea of where the bug is.

Re: Problem with far jump ptr16:32 and data descriptor in GD

Posted: Tue Jan 05, 2016 12:43 pm
by startrail
TightCoderEx wrote:SZ should probably be 1 for 32 bit protected mode so both instances of 4F in GDT should be CF.
Wouldn't that mean that paging enabled? Since I haven't enabled paging yet, I left it at 0x4f. Even then trying with 0xcf only changes the limit of code segment to 0xffffffff. Other segments remain the same.

@ggodw000
Before going to pmode I check the values in all the fields of the data descriptor (the 3rd from start) just to be sure. But as soon as I go to pmode and try to print the contents of the data in those fields again by writing to video memory directly the system triple faults since I try to write beyond the limit of the data segment (0xb8000 > 0xffff+0x100). Can it be ruled out as a VM problem then? I don't have CD-ROM in my laptop, so I can't test the code on a real machine.

PS : A new issue has arised. When I load the TSS with ltr, the system doesn't even read the segments from GDT. It just hangs.

Re: Problem with far jump ptr16:32 and data descriptor in GD

Posted: Tue Jan 05, 2016 1:01 pm
by ggodw000
startrail wrote:
TightCoderEx wrote:SZ should probably be 1 for 32 bit protected mode so both instances of 4F in GDT should be CF.
Wouldn't that mean that paging enabled? Since I haven't enabled paging yet, I left it at 0x4f. Even then trying with 0xcf only changes the limit of code segment to 0xffffffff. Other segments remain the same.

@ggodw000
Before going to pmode I check the values in all the fields of the data descriptor (the 3rd from start) just to be sure. But as soon as I go to pmode and try to print the contents of the data in those fields again by writing to video memory directly the system triple faults since I try to write beyond the limit of the data segment (0xb8000 > 0xffff+0x100). Can it be ruled out as a VM problem then? I don't have CD-ROM in my laptop, so I can't test the code on a real machine.

PS : A new issue has arised. When I load the TSS with ltr, the system doesn't even read the segments from GDT. It just hangs.
triple fault is most likely to due to IDT I think. if you do int 15h or int 21h to print to screen, then you are invoking software interrupt so you'd need to initialize interrupt descriptor table, which is what i am trying to get it to work also.

Re: Problem with far jump ptr16:32 and data descriptor in GD

Posted: Tue Jan 05, 2016 1:07 pm
by startrail
No, I didn't use any int to print screen. Instead I am directly writing char/attribute to the video memory at 0xb8000 with something like

Code: Select all

mov ebx,0x000b8000
mov [ebx],dx   ;dx has the attrib/char

Re: Problem with far jump ptr16:32 and data descriptor in GD

Posted: Tue Jan 05, 2016 1:44 pm
by Gigasoft
You never actually load anything from your GDT. You have to turn on CR0.PE first.

Re: Problem with far jump ptr16:32 and data descriptor in GD

Posted: Tue Jan 05, 2016 4:47 pm
by ggodw000
Gigasoft wrote:You never actually load anything from your GDT. You have to turn on CR0.PE first.
looks like he did???

mov eax,cr0
or eax,1
mov cr0,eax

Re: Problem with far jump ptr16:32 and data descriptor in GD

Posted: Tue Jan 05, 2016 4:51 pm
by ggodw000
startrail wrote:No, I didn't use any int to print screen. Instead I am directly writing char/attribute to the video memory at 0xb8000 with something like

Code: Select all

mov ebx,0x000b8000
mov [ebx],dx   ;dx has the attrib/char
ok there is something else then. Some1 suggested me using bochs but i hated it after trying to get it work for hours, IMO, it is **** crap software (sorry if it is some1's favourite).
I usually put jmp $ instruction to where I think it might be 3-faulting.
so you fire up your system and if it 3-faults, move the jmp $ few lines up and re-compile and see if it 3-faults. If it does not and system "freezes" then it is continually jumping to current location then you know it is not 3-faulting. That is how I pinpointed the exact point it was 3-fault. In mycase, gdt ptr was wrong and I had to correct by putting flat address of gdt (was using seg:off address)

Re: Problem with far jump ptr16:32 and data descriptor in GD

Posted: Tue Jan 05, 2016 5:13 pm
by Gigasoft
No, he did it afterwards. When he loads the segment registers, CR0.PE has not been turned on yet. That is not going to work.

Re: Problem with far jump ptr16:32 and data descriptor in GD

Posted: Tue Jan 05, 2016 5:36 pm
by ggodw000
Gigasoft wrote:No, he did it afterwards. When he loads the segment registers, CR0.PE has not been turned on yet. That is not going to work.
it should work. at least the ones i have seen i.e. code examples and the way i did it, always LGDT and turn on PE. the reverse way you mention, i am not sure will work never tried. it may probably does not matter.
from my experience, the moment of truth seems to be happen when you actually load the segment register with the selector values. if you dont load it, then even something is wrong in the GDT, it still not triple fault.