[SOLVED] Jump to protected mode causes reboot

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
g00dgame
Posts: 2
Joined: Mon Sep 10, 2018 5:10 am
Libera.chat IRC: dithmer

[SOLVED] Jump to protected mode causes reboot

Post by g00dgame »

I know, there are lots of topics similiar to this. I have tried out a lot of the solutions I found on google, and this forum. And nothing really helped. So I try my luck here.

My problem is the following:
I am just starting to develop a bootloader. I use this tutorial as a learning source:
https://github.com/cfenollosa/os-tutorial

I am at the point where I try to get into protected mode. The thing is, that the code I wrote, (mostly the same as the tutorials code) is working in qemu, but not if I write and boot it from a USB stick on my Notebook. I have already tried different settings in the GDT, for 64-Bit mode and so on. In the moment where I try to boot it from a USB-Stick it just restarts, but it doesn't in qemu, so I don't really have a chance to debug it in a development environment. Here is my code:

main.asm

Code: Select all

[bits 16]
[org 0x7c00]

start:
    call switch_to_pm
    jmp $

%include "./include/gdt.asm"
%include "./include/32bit-print.asm"
%include "./include/32bit-switch.asm"

[bits 32]

BEGIN_PM:
    mov ebx, MSG_PROT_MODE
    call print_pm
    cli
    hlt

MSG_PROT_MODE db 'Started prot mode', 0
BOOTSTRING_START db 'Started bootloader', 0

times 510 - ($ - $$) db 0
dw 0xaa55
gdt.asm

Code: Select all

[bits 16]
gdt:
    dd 0x00
    dd 0x00

gdt_code:
    dw 0xffff
    dw 0x0000
    db 0x00
    db 10011010b
    db 11001111b
    db 0x00
    
gdt_data:
    dw 0xffff
    dw 0x0000
    db 0x00
    db 10010010b
    db 11001111b
    db 0x00

gdt_end:

gdt_descriptor:
    dw gdt_end - gdt - 1
    dd gdt

CODE_SEG equ gdt_code - gdt
DATA_SEG equ gdt_data - gdt
32bit-print.asm

Code: Select all

[bits 32]
VIDEO_MEMORY equ 0xb8000
WHITE_ON_BLACK equ 0x0f

print_pm:
    pusha
    mov edx, VIDEO_MEMORY

.loop:
    mov al, [ebx]
    mov ah, WHITE_ON_BLACK

    cmp al, 0
    je .done

    mov [edx], ax
    add ebx, 1
    add edx, 2

    jmp .loop

.done:
    popa
    ret
32bit-print.asm

Code: Select all

[bits 16]

switch_to_pm:
    cli
    lgdt [gdt_descriptor]

    mov eax, cr0
    or eax, 0x1
    mov cr0, eax
    jmp CODE_SEG:init_pm

[bits 32]
init_pm:
    mov ax, DATA_SEG
    mov ds, ax
    mov ss, ax
    mov es, ax
    mov fs, ax
    mov gs, ax

    mov ebp, 0x90000
    mov esp, ebp

    call BEGIN_PM
I do assemble it on a Linux Machine with the following commands (and running in qemu):

Code: Select all

nasm -f bin -o bootloader.bin bootloader.asm
qemu-system-x86-64 bootloader.bin
Writing to the USB-Stick:

Code: Select all

sudo dd if=bootloader.bin of=/dev/sdb bs=512 count=1
I should also mention, that I've got to work everything in before of the tutorial, including reading sectors from the disk/USB-Stick. So it shouldn't be a problem with Floppy/HDD-Emulation.

I am pretty thankful for any help. I would love to go on, but doesnt want to advance in things before I do understand everything before.

Greetings
Last edited by g00dgame on Mon Sep 10, 2018 6:49 am, edited 1 time in total.
g00dgame
Posts: 2
Joined: Mon Sep 10, 2018 5:10 am
Libera.chat IRC: dithmer

Re: Jump to protected mode causes reboot

Post by g00dgame »

I found the solution.

A standard, and really silly mistake. I was not setting my Data- and Extrasegments correctly in Real Mode. So my CPU initialized it with something not 0x0. QEMU seems to initialize it with 0x0. So it worked in QEMU and not on my Notebook, 'cause the CPU didn't see the correct GDT.

Hope that also helps other people.
Post Reply