Hey Guys

I have been writing my own boot loader and have followed loads of examples and have got together one that pretty much does what i want except when i switch to protected mode it crashes and reboots the machine here is the code.


Code:
; ------------------------------------------------------------------------
; Phoenix OS boot loader           (c)2002 Peter Liddle
; ------------------------------------------------------------------------
; This code is the boot loader for the Phoenix OS
; ------------------------------------------------------------------------
[BITS 16]		;Set code generation to 16 bit mode
[ORG 0x0000]	;Tell compiler this si offset 0, it isn;t but will be after jump

jmp BOOT


; -------------------------------------
; Data section
; ------------------------------------------------------------------------
DATA:	
	BootDrv		db	0x80

	BootMsg		db	'Booting Phoenix OS', 0x0D, 0x0A, 0	
	PModeMsg	db      'Jumping to Protected Mode', 0x0D, 0x0A, 0
	PModeEnabledMsg	db      'Where in Protected Mode at Last', 0x0D, 0x0A, 0

	EnablA20Msg	db	'Enabling A20 Line', 0x0D, 0x0A, 0
	A20EnabledMsg	db	'A20 Line is Now Turned On', 0x0D, 0x0A, 0

	IDTptr          DW 7FFh			;LIMIT 256 IDT Slots
			DD 0000h		;BASE (Linear)

	GDTptr          DW 17FFh		;LIMIT 768 slots
			DD 0800h		;BASE (Linear)

; ------------------------------------------
; Functions section
; ------------------------------------------------------------------------
.386
RESETDISK:                      ; Reset drive
	mov ax, 0           	;
        mov dl, [BootDrv]	; Drive=BootDrv
        int 13h             	; Actually Reset
        jc RESETDISK           	; ERROR => reset again
	ret

READ:
	mov ax, 0x1000      	; ES:BX = 0x1000:0000
        mov es, ax          	;
        mov bx, 0           	;

	call RESETDISK		; First Reset Disk
        mov ah, 0x2         	; Load disk data to ES:BX
        mov al, 0x1    		; Load 1 sectors
        mov ch, 0x0    		; Track=1
        mov cl, 0x2    		; Sector=2
        mov dh, 0x00        	; Head=0
        mov dl, [BootDrv] 	; Drive=BootDrv
        int 13h             	; Read!

        jc READ             	; ERROR => Try again
	ret

PRINTMSG:                       ; Dump ds:si to screen.
        lodsb                   ; load byte at ds:si into al
        or al,al                ; test if character is 0 (end)
        jz done
        mov ah,0eh              ; put character
        mov bx,0007             ; attribute
        int 0x10                ; call BIOS
        jmp PRINTMSG
   done:
        ret

CLEARBUF:
	XOR CX,CX
        in al, 64h              ; get input from keyboard status port
        test al, 02h            ; test the buffer full flag
        loopnz CLEARBUF	        ; loop until buffer is empty
	ret
; ------------------------------------------------------------------------



; ------------------------------------------
; Boot Code
; ------------------------------------------------------------------------
BOOT:
	

	;mov [BootDrv],dl	; Save Boot Drive
	
	;Set up Location of Data Segment
	mov ax,0x7C0
	mov ds,ax

	
	cli             	; Turn Off interrupts while we setup a stack and A20 and Get to P-Mode        
        
	;Set Up Stack
	mov ax,0x9000   	; this seems to be the typical place for a stack
        mov ss,ax
        mov sp,0xFFFF		; let's use the whole segment.  Why not?  We can :)
        

	mov si,BootMsg		; display our startup message
	call PRINTMSG

	;call READ		; Load in a sector
   
	;Enable A20 Address Line
	mov si,EnablA20Msg	; display our startup message
	call PRINTMSG


	;Turn on A20 Line
      
	call CLEARBUF		; Wait till keyboard Buffer is empty
	
	mov al, 0D1h            ; keyboard: write to output port
	out 64h, al             ; output command to keyboard
	
	call CLEARBUF		; Wait till keyboard Buffer is empty again

	mov al, 0x0DF           ; keyboard: set A20
	out 0x60, al            ; send it to the keyboard controller
	mov cx, 0x14

	call CLEARBUF		; Wait 25 sec for A20 to be enabled
	
	nop
	nop

	mov si,A20EnabledMsg	; display our startup message
	call PRINTMSG
	

	;Lets Get Into P-Mode
	mov si, PModeMsg
	call PRINTMSG


	; Set Global Descriptor Table here, this must be done PRIOR to Prot Mode
	LIDT [IDTptr]
	LGDT [GDTptr]
	
	mov eax, CR0		; load the control register in
	or  eax, 1              ; set bit 1: pmode bit
	mov CR0, EAX            ; copy it back to the control register
	jmp $+2			; and clear the prefetch queue
	nop
	nop

	db		066h, 0EAh
	dw		prot, 06h
	dw		08h


[BITS 32]
prot:	
	; Set up segments
	mov ebx, 10h
	mov ds, bx
	mov es, bx
	mov fs, bx
	mov gs, bx

	mov si, PModeEnabledMsg
	call PRINTMSG


	MOV BX, 10h
	MOV DS,BX
	MOV ES,BX
	MOV FS,BX
	MOV GS,BX
	MOV SS,BX

	;jmp 0x1000:0000


times 510-($-$$) db 0
dw 0xAA55