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
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