Page 1 of 1

PMode Problems

Posted: Tue Dec 09, 2008 12:06 pm
by Firestryke31
I've reached the point where I'm ready for the transition to protected mode, however I seem to be incapable of getting it right. I've tried everything I can think of, and am at the point of copy/pasting someone else's code (which I really don't like doing). I've compared my code to several places, and nothing looks out of place, but whenever I do the far jump to load CS, Bochs triple-faults and starts over.

Here's my PMode code, GDT, & GDTR:

Code: Select all

bits 16
;; stuff
	cli
	lgdt [FBGDTR]
	mov eax, CR0
	or al, 1
	mov CR0, eax
	
	jmp 0x08:pMode

;; 16 bit routines

bits 32
pMode:
	;; Stuff that's never reached

FBGDT:
.gdtnull:
	dd 0
	dd 0

.gdtcs:
	dw 0FFFFh
	dw 0
	db 0
	db 10011010b
	db 11001111b
	db 0
	
.gdtds:
	dw 0FFFFh
	dw 0
	db 0
	db 10010010b
	db 11001111b
	db 0

FBGDTEND:

FBGDTR:
	dw FBGDTEND - FBGDT - 1
	dd FBGDT
And here's the Bochs dump from MBR load to triple-fault:

Code: Select all

00023582386i[BIOS ] Booting from 0000:7c00
00023598390e[CPU0 ] fetch_raw_descriptor: GDT: index (f)1 > limit (0)
00023598390i[CPU0 ] CPU is in protected mode (active)
00023598390i[CPU0 ] CS.d_b = 16 bit
00023598390i[CPU0 ] SS.d_b = 16 bit
00023598390i[CPU0 ] EFER   = 0x00000000
00023598390i[CPU0 ] | RAX=0000000060000011  RBX=0000000000000200
00023598390i[CPU0 ] | RCX=0000000000000838  RDX=0000000000000180
00023598390i[CPU0 ] | RSP=0000000000007fe6  RBP=0000000000008000
00023598390i[CPU0 ] | RSI=0000000000007a00  RDI=0000000000080400
00023598390i[CPU0 ] |  R8=0000000000000000   R9=0000000000000000
00023598390i[CPU0 ] | R10=0000000000000000  R11=0000000000000000
00023598390i[CPU0 ] | R12=0000000000000000  R13=0000000000000000
00023598390i[CPU0 ] | R14=0000000000000000  R15=0000000000000000
00023598390i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df if tf sf zf af PF cf
00023598390i[CPU0 ] | SEG selector     base    limit G D
00023598390i[CPU0 ] | SEG sltr(index|ti|rpl)     base    limit G D
00023598390i[CPU0 ] |  CS:0000( 0004| 0|  0) 00000000 0000ffff 0 0
00023598390i[CPU0 ] |  DS:0000( 0005| 0|  0) 00000000 0000ffff 0 0
00023598390i[CPU0 ] |  SS:0000( 0005| 0|  0) 00000000 0000ffff 0 0
00023598390i[CPU0 ] |  ES:0000( 0005| 0|  0) 00000000 0000ffff 0 0
00023598390i[CPU0 ] |  FS:0000( 0005| 0|  0) 00000000 0000ffff 0 0
00023598390i[CPU0 ] |  GS:0000( 0005| 0|  0) 00000000 0000ffff 0 0
00023598390i[CPU0 ] |  MSR_FS_BASE:0000000000000000
00023598390i[CPU0 ] |  MSR_GS_BASE:0000000000000000
00023598390i[CPU0 ] | RIP=0000000000008082 (0000000000008082)
00023598390i[CPU0 ] | CR0=0x60000011 CR1=0x0 CR2=0x0000000000000000
00023598390i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
00023598390i[CPU0 ] >> jmp far 0008:81a7 : EAA7810800
00023598390e[CPU0 ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting
00023598390i[SYS  ] bx_pc_system_c::Reset(SOFTWARE) called
00023598390i[CPU0 ] cpu software reset
Is there something special about where the GDT/GDTR is (i.e. dword aligned or something) that I've missed?

Re: PMode Problems

Posted: Tue Dec 09, 2008 1:02 pm
by Dex
This is the very basic's you need

Code: Select all

;************************************
; Basic pmode demo   by Dex
;
;************************************
org 0x7C00 

use16
;****************************
; Realmode startup code.
;****************************
start:
        xor   ax,ax
        mov   ds,ax
        mov   es,ax
        mov   ss,ax
        mov   sp,0x7C00 
;*****************************
; Setting up, to enter pmode.
;*****************************
        cli 
        lgdt  [gdtr]

        mov   eax, cr0
        or    al,0x1 
        mov   cr0,eax

        jmp   0x10: protected
;*****************************
; Pmode. ;-)
;*****************************
use32
protected:
        mov   ax,0x8 
        mov   ds,ax
        mov   es,ax
        mov   ss,ax
        mov   esp,0x7C00
;*****************************
; Turn floppy off 
;*****************************
        mov   dx,3F2h
        mov   al,0
        out   dx,al

        jmp   $
;*************************************
; GDT. 
;*************************************
gdt:        dw    0x0000, 0x0000, 0x0000, 0x0000
sys_data:   dw    0xFFFF, 0x0000, 0x9200, 0x00CF
sys_code:   dw    0xFFFF, 0x0000, 0x9800, 0x00CF
gdt_end:

gdtr:	    dw gdt_end - gdt - 1	
            dd gdt 

;*************************************
; Make program 510 byte's + 0xaa55
;*************************************

times 510- ($-start)  db 0  
dw 0xaa55


NOTE: You can edit out the "Turn floppy off " code, then if your floppy light stays on you know your in pmode.

Re: PMode Problems

Posted: Tue Dec 09, 2008 1:37 pm
by Firestryke31
The problem is, that's more or less what I have. Bochs triple faults on reaching the jump, and I can't figure out why.

The only thing I can see in the log file that's in any way relevant to the problem is this:
bochs.log wrote:00023598390e[CPU0 ] fetch_raw_descriptor: GDT: index (f)1 > limit (0)
But I can't see what's wrong with my GDT... Image

Re: PMode Problems

Posted: Tue Dec 09, 2008 1:50 pm
by kmtdk
well
i just tried you code
and i think i know the reason
when you use "LGDT" it uses "DS" as the seg, and then the address you have given
so if DS = 0x0100, and the "address" is 0x7e00
then it will load (0x0100*10) + 0x7e00 = 0x8e00
so there is only 1 thing you will have to do, in order to make you example working ( i used fasm )
insert a "org 0x7c00"
at the beging
place it a the first sector, boot
THIS WILL NOT work on a real computer, cause it normaly boots with the address: 0x07c0 : 0x0000
so chaning ds is maby the solution

KMT dk

Re: PMode Problems

Posted: Tue Dec 09, 2008 1:57 pm
by Combuster
Other than my computers systematically booting from 0000:7c00, kmtdk is right - you should set DS (and for good measure, CS) to zero, and add the org statement.

Re: PMode Problems

Posted: Tue Dec 09, 2008 3:31 pm
by sebihepp
Hello,

lgdt needs the physical address to the GDT. So if this code is in Segment 0x07C0, then
try it with lgdt [GDT + 0x7C00].

CHeers
Sebihepp

Re: PMode Problems

Posted: Tue Dec 09, 2008 3:37 pm
by Firestryke31
The bochs dump in my first post indicates that DS is, in fact, 0.
bochs.log wrote: 00023598390i[CPU0 ] | DS:0000( 0005| 0| 0) 00000000 0000ffff 0 0
Also, I forgot to mention that this code is in my second stage, which is loaded by my FAT32 bootloader. The 2nd stage code does some other stuff before it gets to the pMode enabling, but the Bochs dump in my first post shows the values of all of the registers at the time of the fault.

Re: PMode Problems

Posted: Tue Dec 09, 2008 6:20 pm
by tantrikwizard
Firestryke31 wrote:The bochs dump in my first post indicates that DS is, in fact, 0.
bochs.log wrote: 00023598390i[CPU0 ] | DS:0000( 0005| 0| 0) 00000000 0000ffff 0 0
Also, I forgot to mention that this code is in my second stage, which is loaded by my FAT32 bootloader. The 2nd stage code does some other stuff before it gets to the pMode enabling, but the Bochs dump in my first post shows the values of all of the registers at the time of the fault.
immediately after LGDT use the 'info gdt' command in the console to see how its layed out. If bochs reports what you expect then something else is going on.

Re: PMode Problems

Posted: Tue Dec 09, 2008 7:05 pm
by Firestryke31
Okay, I did that and it seems that lgdt isn't getting the right address. I'm going to try moving some stuff around and renaming in case of some conflict YASM isn't telling me about...

<Off topic>
Also, I abhor the default Bochs debugger. Unfortunately, the only other 2 I could find either required me to recompile Bochs from source or use an out of date version.
</Off topic>

Re: PMode Problems

Posted: Tue Dec 09, 2008 7:25 pm
by tantrikwizard
Firestryke31 wrote:Also, I abhor the default Bochs debugger.
get used to it. noone likes it but its the only free alternative of its kind.

Re: PMode Problems

Posted: Tue Dec 09, 2008 7:32 pm
by Firestryke31
Well, it seems that the biggest problem I've been having is that my code for loading the second stage seems to only be loading one sector, while the file is 2. Of course, the actual code is in the 1st sector, and the data (including the GDT & GDTR) are in the 2nd. Now I get to go through and try to figure out why my boot sector only loads the 1st sector. Whee. Image

Re: PMode Problems

Posted: Tue Dec 09, 2008 7:38 pm
by quok
tantrikwizard wrote:
Firestryke31 wrote:Also, I abhor the default Bochs debugger.
get used to it. noone likes it but its the only free alternative of its kind.
Well, not quite. Two forums members have created an enhanced debugger GUI for bochs. Bewing's version of it is even in Bochs CVS, and he's got a GTK version of it that he's asking people to test. There's a couple of threads on here somewhere about them. Of course, there is some compiling involved...

Also, you could always use qemu instead of bochs and attach GDB to it if you prefer GDB. Once again, I'll also suggest using Insight, which is a GUI that is tightly integrated with GDB. That is, it's not some hokey add-on but directly compiled in. It's every bit as easy to use as GDB, and the GUI even offers the traditional GDB 'console' if you'd prefer command line. If anyone wants a little tutorial on how to use that, I'd be happy to oblige.

Re: PMode Problems

Posted: Tue Dec 09, 2008 7:42 pm
by tantrikwizard
quok wrote:If anyone wants a little tutorial on how to use that, I'd be happy to oblige.
This would be nice (at least for windows developers like me) I tried the gdb stubs for qemu before under cygwin and didnt get very far. Does gdb display the GDT/LDT/IDT?

Re: PMode Problems

Posted: Tue Dec 09, 2008 10:29 pm
by Firestryke31
Alright, I fixed the problem. In my bootloader, while I was loading the second stage, I forgot to set my CurrentCluster 'variable' to the first cluster of the file, meaning it kept the old cluster, which happened to be the first cluster of the root directory. So it loaded the first cluster of the second stage, then loaded the rest of the root directory instead of the rest of the second stage (which had the GDT, along with some other stuff).

Now I'm in pMode, and just found out that I got the ASCII character and attribute backwards in my cls and putStr32 routines. Hopefully this will be more easily fixed than the problem I had before! Image