segmentation fault when trying to jump in 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
User avatar
yemista
Member
Member
Posts: 299
Joined: Fri Dec 26, 2008 12:31 pm
Location: Boston
Contact:

segmentation fault when trying to jump in protected mode

Post by yemista »

I have attached the code for my boot loader. It tries to load code past the 1MB mark, setup protected mode, and then jump into it, but it gets a segmentation fault. However, when I try to make the jump without being in pmode, the code will work.

[BITS 16] ; 16 bit code generation
[ORG 0x7C00] ; Origin location

;; setup ds
mov ax,0x0000
mov ds,ax
jmp enableA20

;; various strings used
A20success db 'A20 enabled!',13,10,0
failure db 'FAILURE!',13,10,0
hello db 'loading...',13,10,0

;; data structure to load the gdtr with
gdtr dw 0 ;; size of entry
dd 0 ;; offset

;; actual gdt entry
;; i dont know what these mean because i sat down and worked them
;; out. see http://wiki.osdev.org/GDT for details
gdt dd 0 ;; this is the null descriptor
dd 0
dd 0xffff0000 ;; this is the cs descriptor
dd 0x00984f00
dd 0xffff0000 ;; this is the ds dsecriptor
dd 0x00924f00

gdt_end

print:
;; i took this part from http://www.osdever.net/tutorials/hello_btldr.php
mov ah,0x0E ; The function to display a chacter (teletype)
mov bh,0x00 ; Page number
mov bl,0x07 ; Normal text attribute

.nextchar
lodsb ; this incremeents si
or al,al ; check if were done
jz .done
int 0x10 ; Run the BIOS video interrupt
jmp .nextchar ; Loop back round tothe top
.done ; Label at the end to jump to when complete
ret ; Return to main program

enableA20:
mov si, hello
call print
;; enable the A20 line
cli

call .a20wait
mov al, 0xad
out 0x64, al

call .a20wait
mov al, 0xd0
out 0x64, al

call .a20wait2
in al, 0x60
push eax

call .a20wait
mov al, 0xd1
out 0x64, al

call .a20wait
pop eax
or al, 2
out 0x60, al

call .a20wait
mov al, 0xae
out 0x64, al

call .a20wait
sti

;; test to see if line is enabled by checking to make
;; sure RAM doesnt wrap around over 1MB
mov ax, 0xffff
mov es, ax
mov ax, [es:0x7e0e]
cmp ax, 0xaa55
jnz A20enabled

;;; else boot failed
jmp boot_failure

.a20wait:
in al, 0x64
test al, 2
jnz .a20wait
ret

.a20wait2:
in al, 0x64
test al, 1
jz .a20wait2
ret

;; otherwise we cannot continue to boot
boot_failure:
mov si, failure
call print
jmp boot_failure

A20enabled:
mov si, A20success
call print

;; now we setup a temporary gdt and enter pmode
;; this temp gdt gives us flat 4gb address space with cs=ds
xor eax, eax
add eax, gdt
mov [gdtr+2], eax ; set offset of gdt
mov eax, gdt_end
sub eax, gdt ; calculate the size of the table
mov [gdtr], ax ; set the size in the entry
lgdt [gdtr] ; now load it

;; now setup the selectors to point into the gdt
mov ax, 0x10
mov ds, ax
mov es, ax
mov gs, ax
mov fs, ax

;; now we can finally load the kernel
mov dl, 0x00 ;; we want floppy drive 1
mov ah, 0x02 ;; read from floppy
mov dh, 0x00 ;; i think 0 is the first head...
mov cx, 0x02 ;; i think this means the second sector...
mov bx, 0xffff
mov es, bx
mov bx, 0x0011 ;; we load to start of memory
int 0x13 ;; BIOS int loads code to es:bx

cli

;; enter pmode by changing one bit in cr0
mov eax, cr0
or eax, 0x01
mov cr0, eax


jmp dword 0x08:0x00100001

; end of bootsector
times 510-($-$$) db 0 ; Fill the rest with zeros
dw 0xAA55 ; Boot loader signature

[bits 32]

start:
sti
mov ax, 0x55
User avatar
yemista
Member
Member
Posts: 299
Joined: Fri Dec 26, 2008 12:31 pm
Location: Boston
Contact:

Re: segmentation fault when trying to jump in protected mode

Post by yemista »

also, theres one thing i really dont get that ive seen working bootloaders do. when you switch between 16 bit real mode and then suddenly go to 32 bit pmode, how can references youve setup in real mode still work in pmode? for example, the location of the gdt, or referring to a function you wrote back when you were still using real mode.
JohnnyTheDon
Member
Member
Posts: 524
Joined: Sun Nov 09, 2008 2:55 am
Location: Pennsylvania, USA

Re: segmentation fault when trying to jump in protected mode

Post by JohnnyTheDon »

You have to convert your real mode segment:offset address to a physical address. Just left shift the real mode segment 4 bits and add it to the offset.

EDIT: accidentally wrote s**t instead of shift...
Last edited by JohnnyTheDon on Sat Jan 03, 2009 9:59 pm, edited 1 time in total.
User avatar
yemista
Member
Member
Posts: 299
Joined: Fri Dec 26, 2008 12:31 pm
Location: Boston
Contact:

Re: segmentation fault when trying to jump in protected mode

Post by yemista »

ok i think i know whats going on, but i have no idea. my only theory is, if you enable a20 in real mode, do you
have to do it again in pmode? Thats all that makes sense. Pmode seems to be working, but when i do a far
jump to 0x00100001, the segmentation fault occurs at 0x0000ffff. For test purposes, I changed the far jump
to 0x00100002, and the segmentation fault occurred at 0x00000001. It seems like it cant get to that 20th bit, but I dont see why enabling A20 in real mode wouldnt mean that it was enabled in pmode, but then again, all the source code I looked at seems to enable it after being in pmode.
User avatar
yemista
Member
Member
Posts: 299
Joined: Fri Dec 26, 2008 12:31 pm
Location: Boston
Contact:

Re: segmentation fault when trying to jump in protected mode

Post by yemista »

never mind, the problem was that pmode segments still have limits, and the max limit of a segment is still only 1MB. I am not using paging by the way
Post Reply