Page 1 of 1

Qemu resets after attempting to switch to protected mode

Posted: Sun Feb 04, 2018 1:17 pm
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

Re: Qemu resets after attempting to switch to protected mode

Posted: Sun Feb 04, 2018 6:51 pm
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.

Re: Qemu resets after attempting to switch to protected mode

Posted: Sun Feb 11, 2018 3:15 pm
by FallenAvatar
You can't compile real mode code with GCC. Also, use bochs to get more debugging information.

- Amy

Re: Qemu resets after attempting to switch to protected mode

Posted: Sun Feb 11, 2018 3:29 pm
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.

Re: Qemu resets after attempting to switch to protected mode

Posted: Sun Feb 11, 2018 3:36 pm
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.