Tripple fault after long jump to protected mode

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
onlshk
Posts: 9
Joined: Wed Sep 24, 2014 2:42 am

Tripple fault after long jump to protected mode

Post by onlshk »

Hello all,

I wrote simple bootloader and trying to jump to protected mode, but bochs reboots everytime after jump.

Here is first stage of bootloader. It loads at 0x7c00 and loads second stage:

Code: Select all

bits 16
[org 0x7c00]

ot:
		; All segments set to 0, flat memory model
		;; initialize segment registers
		mov ax, 0
		mov es, ax
		mov ds, ax
		mov ss, ax
		mov gs, ax
		mov fs, ax
		mov sp, 4096

		;;-------------------------
		;; reset disk
		mov ah, 0x00  ; reset function
		mov dl, 0x00  ; drive
		int 0x13   ; disk int
		jc diskResetFailMsg

		;;-------------------------
		;; load 'asm' kernel
		mov bx, 0x7e0 ;segment
		mov es, bx
		mov bx, 0x000 ; offset

		mov ah, 0x02
		mov al, 0x03
		mov ch, 0x00
		mov cl, 0x02
		mov dh, 0x00
		mov dl, 0x00
		int 0x13

		;; check error loading
		jc diskReadFailMsg
		;; jump to header
		jmp dword 0x0000:0x7e00

;; finish boot sector
times 510-($-$$) db 0
dw 0xaa55
Here is my second stage. It loads gdt and here i'm trying to jmp to protected mode:

Code: Select all

[bits 16]
[org 0x7e00]

_start:
        ;; dissable interupts
        cli

        ;; load descriptor data table
        lgdt [gdt_descriptor]

        ;; switch to protected mode
        mov eax, cr0
        or al, 0x1
        mov cr0, eax

        jmp CODE_SEG:PMode

[BITS 32]
PMode:
        hlt
        jmp $

;;
;; Global descriptor table
;;
gdt_start:

gdt_null:
	;; null selector
        dd 0
        dd 0

gdt_code:
        dw 0xffff
	dw 0
	db 0
	db 10011010b
	db 11001111b
	db 0

gdt_data:
	dw 0xffff
	dw 0
        db 0
        db 10010010b
	db 11001111b
	db 0

gdt_end:

gdt_descriptor:
	dw gdt_end - gdt_start - 1
        db gdt_start

times 1024-($-$$) db 0
I'm building it with:

Code: Select all

OS.img: loader.bin stage1.bin
	cat loader.bin > os.bin
	cat stage1.bin >> os.bin
	dd status=noxfer conv=notrunc if=os.bin of=OS.img

loader.bin:	loader.asm
	nasm -w+all -f bin -o loader.bin loader.asm

stage1.bin: stage1.asm
	nasm -w+all -f bin -o stage1.bin stage1.asm
And starting with bochs:

Code: Select all

display_library: sdl
megs: 64
boot: floppy
floppya: 1_44=OS.img, status=inserted
After starting, i'm getting tripple fault and:

Code: Select all

0x0000000000007e67>> jmp far 0008:7e6c : EA6CE0800
exception(): 3rd (13) execption with no resolution, shutdown status is 00h, reseting
Thank you.
Octocontrabass
Member
Member
Posts: 5590
Joined: Mon Mar 25, 2013 7:01 pm

Re: Tripple fault after long jump to protected mode

Post by Octocontrabass »

Code: Select all

		mov ss, ax
		mov gs, ax
		mov fs, ax
		mov sp, 4096
Any instruction that loads SS must immediately be followed by an instruction to load (E)SP. Otherwise, an interrupt may clobber memory unexpectedly.

Code: Select all

		mov dl, 0x00  ; drive
The BIOS will give you the drive number in DL when it jumps to your code. You should avoid hard-coding it, since there are cases where it may not be the value you expect.

Code: Select all

gdt_descriptor:
	dw gdt_end - gdt_start - 1
        db gdt_start
You might want to double-check this.

Code: Select all

0x0000000000007e67>> jmp far 0008:7e6c : EA6CE0800
exception(): 3rd (13) execption with no resolution, shutdown status is 00h, reseting
You should copy and paste the Bochs log instead of retyping it, and post more than just two lines from it.
onlshk
Posts: 9
Joined: Wed Sep 24, 2014 2:42 am

Re: Tripple fault after long jump to protected mode

Post by onlshk »

Yes, there must be dd instead db.... Works now. Many thanks.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Tripple fault after long jump to protected mode

Post by Brendan »

Hi,

This looks wrong to me (the address of the GDT won't fit in 1 byte):

Code: Select all

gdt_descriptor:
	dw gdt_end - gdt_start - 1
        db gdt_start
I'd suggest:

Code: Select all

gdt_descriptor:
	dw gdt_end - gdt_start - 1
        dd gdt_start
Apart from that, the rest looks "mostly right", but there are a few things I'd change.

Code: Select all

bits 16
[org 0x7c00]
This should really be "org 0x7C00" (without the square brackets).

At the very start, you should have a "jmp start" followed by a BPB. Some BIOSs (mostly older compaq machines if I remember right) do test if there's a JMP and assume it's not bootable if it's not there. Without a BPB, other operating systems (mostly Windows) will assume the floppy isn't formatted, and tell the user that the disk is trash and ask if they want the disk formatted. The average user won't understand, will believe Windows, and will think your code has "broken" their floppy disk somehow.

Code: Select all

		mov sp, 4096
If you're assuming that the CPU supports 32-bit (rather than checking first); then it'd be nicer to use "mov esp,0x00001000" to ensure that your stack doesn't end up somewhere different (e.g. at 0x12341000) in protected mode.

Code: Select all

		;; reset disk
This BIOS just loaded your first 512 bytes from disk, therefore you know the disk is working OK and there's no reason to reset it here.

Code: Select all

		mov dl, 0x00
		int 0x13
It's a bad idea to assume "device number 0x00". Use the value the BIOS gave you (in DL) instead.

Code: Select all

		;; check error loading
		jc diskReadFailMsg
For floppy, some failures are normal. You need to retry several times (in case it's just an annoying/temporary problem) before giving up. It's a good idea to add the "reset disk system" as part of the retries (but not necessarily in every retry - e.g. maybe every second retry).

For the error message itself (not shown - I'm making assumptions); it's probably bad to assume that whatever booted you (which may not have been BIOS and could be a "chain-loader") left you in 80*25 text mode, or to assume that the system has a video card or monitor. This means that it's probably a good idea to set the video mode yourself, and also do something else (e.g. make the PCI speaker beep) when you can't boot.
onlshk wrote:Here is my second stage. It loads gdt and here i'm trying to jmp to protected mode:
That's probably a bad idea - eventually you will need to get a memory map from the BIOS first. You may also want to (e.g.) get the monitor's EDID, setup a decent graphical video mode, get details of disk drives, etc.

[EDIT]Ninjas! Left "as was" because I'm lazy.[/EDIT]


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Post Reply