Results 1 to 7 of 7

Thread: Protected Mode

  1. #1

    Thread Starter
    Lively Member
    Join Date
    Sep 2000
    Location
    England
    Posts
    94

    Protected Mode

    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
    "Let's all join forces, rule with an iron hand...and prove to all the world, metal rules the land..."
    -- Judas Priest

    My email is [email protected]

  2. #2
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    I don't really know, but the actions you take at the moment of switching to p would probably be the error. I guess you have a good reason for the db and dw lines there.

    Another possibility is a segmentation fault when you try to print the success message. This seems very likely to me on second reflection.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  3. #3

    Thread Starter
    Lively Member
    Join Date
    Sep 2000
    Location
    England
    Posts
    94
    I managed to fix the problem in the end and for teh benefit of everyone here is my working bootloader.


    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 its at offset 0x000, it isn;t but will be after jump
    
    jmp 0x07C0: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
    	A20EnabMsg		db	'A20 Line is Now Turned On', 0x0D, 0x0A, 0
    	TestMsg			db	'Blah Blah Blah', 0x0D, 0x0A, 0
    
    	GDT:            ; our descriptors
    	; NULL descriptor
    	dw 0              ; limit 15:0
    	dw 0              ; base 15:0
    	db 0              ; base 23:16
    	db 0              ; type
    	db 0              ; limit 19:16, flags
    	db 0              ; base 31:24
    
    	; unused descriptor	
    	dw 0
    	dw 0
    	db 0
    	db 0
    	db 0
    	db 0
    
    	; data segment descriptor
    	LINEAR_DATA_SEL	EQU $-GDT
    	dw 0FFFFh			; limit 0xFFFF (1 meg, 4 gig)
    	dw 0				; base for this line is always 0
    	db 0
    	db 92h				; present, ring 0, data, expand-up, writable
    	db 0CFh				; page-granular (4 gig limit), 32-bit
    	db 0
    
    	; code segment descriptor
    	LINEAR_CODE_SEL	EQU $-GDT
    	dw 0FFFFh			; limit 0xFFFF (1 meg, 4 gig)
    	dw 0				; base for this line is always 0
    	db 0
    	db 9Ah				; present, ring 0, code, non-conforming, readable
    	db 0CFh				; page-granular (4 gig limit), 32-bit
    	db 0
    	GDT_END:
    	
    	GDTptr:
    		dw GDT_END - GDT - 1	; GDT limit
      		dd 0x07C00 + GDT			; linear, physical address of GDT 
    
    
    ; ------------------------------------------
    ; 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, 0x2				; Load 1 sectors
    	mov ch, 0x0				; Track=1
    	mov cl, 0x8				; 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 ax,0x7C0				; Set The data Segment to right address
    	mov ds,ax
    
    	mov eax,0x0000				; Zero all other irrelevant segments
    	mov ES,ax
    	mov FS,ax
    	mov GS,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 :)
    
    	sti					; Turn interupts back on
    
    	mov si,BootMsg				; display our startup message
    	call PRINTMSG
    
    	;Enable A20 Address Line
    	mov si,EnablA20Msg			; display our startup message
    	call PRINTMSG
    
    
    	;Read in Next Bit for Loading
    	call READ				; Load in a sector
    
    	
    	cli					; Turn interupts off again
    
    	;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
    
    	sti					; Turn interupts back on
    	
    	
    	mov si,A20EnabMsg			; display our startup message
    	call PRINTMSG
    
    	cli					; Turn interupts off again
    
    	;Lets Get Into P-Mode
    	mov si, PModeMsg
    	call PRINTMSG
    
    	; Set Global Descriptor Table here, this must be done PRIOR to Protected Mode
    	LGDT [GDTptr]
    	
    	;Lets Get Into P-Mod
    	mov EAX, CR0				; load the control register in
    	or  EAX, 0x1				; set bit 1: pmode bit
    	mov CR0, EAX				; copy it back to the control register
    	;jmp $+2
    	;nop
    	;nop
    	;mov EAX,GDTptr
    
    	jmp LINEAR_CODE_SEL:PMODECODE + 0x7c00
    
    
    [BITS 32]
    PMODECODE:
    
    mov EAX, LINEAR_DATA_SEL
    mov ds,EAX
    mov es,EAX
    mov fs,EAX
    mov gs,EAX
    
    
    here:
    	jmp	0x1000:0000
    	jmp	here
    
    times 510-($-$$) db 0
    dw 0xAA55
    "Let's all join forces, rule with an iron hand...and prove to all the world, metal rules the land..."
    -- Judas Priest

    My email is [email protected]

  4. #4
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    Thanks, that's cool. Mind if I use it as a model for my tries?

    Is this a bootstrap or must it be loaded? Cuz it seems a little bit large for a bootstrap...
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  5. #5

    Thread Starter
    Lively Member
    Join Date
    Sep 2000
    Location
    England
    Posts
    94
    Go Ahead i put it up there to help other people after the nightmare of a time i had it took my about 2 weeks to get this properly working.

    Anyway it basically reads in data of the harddisk in sectors which you specify which sectors and amount in the read function. It then enables the A20 line and Switches into protected mode. Eventually i plan to have it then jump to my kernel but i got to sort my kernel first which i plan to write in c.

    Anyway Best of Luck to all who are attempting a bootloader.

    As to your question CornedBee on wether it is a bootstrap or needs to be loaded im guessing you mean does the whole thing fit in 1 sector and comprimes the whole bootloader and the answer is yes this is purely a boot loader compile and copy it to sec 1 of a disk and boot it.

    Peter
    "Let's all join forces, rule with an iron hand...and prove to all the world, metal rules the land..."
    -- Judas Priest

    My email is [email protected]

  6. #6
    Frenzied Member markman's Avatar
    Join Date
    Nov 2000
    Location
    Florida.
    Posts
    1,197
    i htink i recognize your name so you might already be there, but if not, goto www.mega-tokyo.com/forum/

    its an OS-dev board
    Mine can make a red box in 320 mode

    pathetic
    retired member. Thanks for everything

  7. #7

    Thread Starter
    Lively Member
    Join Date
    Sep 2000
    Location
    England
    Posts
    94
    Yeah i am a regular member at the MegaTokyo OS forum its brillant and it was with the help of the people on it i actually managed to get my bootloader working.


    Peter
    "Let's all join forces, rule with an iron hand...and prove to all the world, metal rules the land..."
    -- Judas Priest

    My email is [email protected]

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width