Qemu resets after attempting to switch 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
Mytosus
Posts: 1
Joined: Wed Sep 28, 2016 12:41 pm
Libera.chat IRC: mytosus

Qemu resets after attempting to switch to protected mode

Post by Mytosus »

Hey guys. I decided to take a swing at making a bootloader and I'm having some issues regarding the switch from real to protected mode.
I compile this using the following commands:
x86_84-elf-gcc -c -std=gnu99 --ffreestanding -Wall -Wextra -Werror -nostdlib -o boot.o boot.S
x86_64-elf-gcc -std=gnu99 -ffreestanding -Wall -Wextra -Werror -nostdlib boot.o -Ttext 0x7c00 -o kernel.elf
x86_64-elf-objcopy kernel.elf -O binary os.img

then I run it using:
qemu-system-x86_64 -drive file=os.img,if=floppy,format=raw

Is there anyway I could determine what's wrong here? Possibly a way to know what error qemu is facing if any?

boot.S

Code: Select all

   .code16
    .global _start

_start:
    jmp     real_mode
    .include "print.s"
    .include "disk.s"
    .include "pm_switch.s"


real_mode:
    xor     %ax, %ax
    mov     %ax, %ss
    mov     %ax, %ds
    mov     %ax, %es
    mov     %ax, %fs
    mov     %ax, %gs

    mov     0x8000, %bp
    mov     %bp, %sp

    // Clear Screen
    mov     $0x0600, %ax            // set to clear
    mov     $0x0000, %cx            // from (0, 0)
    mov     $0x184f, %dx            // to (28, 79)
    mov     $0x07, %bh
    int     $0x10

    // Set Cursor to 0,0
    mov     $0x2, %ah           // set cursor position
    mov     $0x0, %bh           // set page number to 0
    mov     $0, %dh           // set row
    mov     $0, %dl           // set column
    int     $0x10

    // Load Kernel into Memory
retry:
	cmp		$5, %ax
	je		abort
	inc		%ax
    call    load_kernel
	jc		retry


    mov		0x1000, %dx
    call    print_hex


    // Enter Protected Mode
    call    enter_pm

abort:
    jmp     abort


//error_msg0:  .asciz "ERROR: failed to read drive parameters. Aborting..."
//error_msg1:  .asciz "ERROR: failed to load kernel. Aborting..."
msg:         .asciz "SUCCESS!"
    . = _start + 510
    .byte 0x55
    .byte 0xaa

    .code32
protected_mode:
    mov     $data_segment, %ax
    mov     %ax, %ss
    mov     %ax, %ds
    mov     %ax, %es
    mov     %ax, %fs
    mov     %ax, %gs

    mov     msg, %ebx
    call    print_pm
pm_switch.s:

Code: Select all

gdt_start:
gdt_null_descriptor:
    // Null descriptor
    .8byte  0x0

gdt_code_descriptor:
    // Code segment

    .2byte  0xffff      // limit 0:15
    .2byte  0x0000      // base 0:15
    .byte   0x00        // base 16:23
    .byte   0b10011010  // Access Byte
    .byte   0b11001111  // Flags  Limit 16:19
    .byte   0x00        // base 24:31

gdt_data_descriptor:
    // Data Segment

    .2byte  0xffff      // limit 0:15
    .2byte  0x0000      // base 0:15
    .byte   0x00        // base 16:23
    .byte   0b10010010  // Access Byte
    .byte   0b11001111  // Flags  Limit 16:19
    .byte   0x00        // base 24:31

gdt_end:

gdt_pointer:
    .2byte  gdt_end - gdt_start - 1
    .4byte  gdt_start

    .set    code_segment, gdt_code_descriptor - gdt_null_descriptor
    .set    data_segment, gdt_data_descriptor - gdt_null_descriptor

enter_pm:
    cli                     // Disable interrupts

    lgdt    (gdt_pointer)   // Load the GDT Descriptor

    mov     %cr0, %eax      // switch to Protected Mode
    or      $0x1, %eax      //
    mov     %eax, %cr0      //

    ljmp    $code_segment,$protected_mode
MichaelPetch
Member
Member
Posts: 799
Joined: Fri Aug 26, 2016 1:41 pm
Libera.chat IRC: mpetch

Re: Qemu resets after attempting to switch to protected mode

Post by MichaelPetch »

Debug with Bochs. It has a very good real mode debugger. You can step through the instructions, review memory and it has diagnostics that can make debugging bootloader code easier.
FallenAvatar
Member
Member
Posts: 283
Joined: Mon Jan 03, 2011 6:58 pm

Re: Qemu resets after attempting to switch to protected mode

Post by FallenAvatar »

You can't compile real mode code with GCC. Also, use bochs to get more debugging information.

- Amy
MichaelPetch
Member
Member
Posts: 799
Joined: Fri Aug 26, 2016 1:41 pm
Libera.chat IRC: mpetch

Re: Qemu resets after attempting to switch to protected mode

Post by MichaelPetch »

You can compile real mode code with GCC if you know what you are doing and you stay within certain constraints. It will be bloated with all the operand and address prefixes and non-trivial programs will require a 386+. in this code he is in real mode and switched to 32-bit protected mode. He's using GCC to assemble his assembly file and then links everything together with GCC.
Last edited by MichaelPetch on Sun Feb 11, 2018 4:08 pm, edited 1 time in total.
MichaelPetch
Member
Member
Posts: 799
Joined: Fri Aug 26, 2016 1:41 pm
Libera.chat IRC: mpetch

Re: Qemu resets after attempting to switch to protected mode

Post by MichaelPetch »

I did notice you are using x86_64-elf-gcc. By default that will generate 64-bit code. The code you have shown us only shows you switching into 32-bit protected mode. 64-bit code will not run properly in 32-bit protected mode. If you want 64-bit code to work you will need to switch to 64-bit long mode. You don't appear to be doing that here. If you want to compile as32-bit code use the GCC -m32 option.
Post Reply