diff --git a/arch/x86_64/src/intel64/intel64_head.S b/arch/x86_64/src/intel64/intel64_head.S index 9ffa25275a..46b72b4f28 100644 --- a/arch/x86_64/src/intel64/intel64_head.S +++ b/arch/x86_64/src/intel64/intel64_head.S @@ -107,6 +107,38 @@ header_start: #endif header_end: + .code16 + .section ".realmode", "ax" + + .type __reset_entry, @function +__reset_entry: + // Load a GDT for protected mode + movl $loader_gdt_ptr, %ebx + lgdtl (%ebx) + + // enable protected mode in CR0 + mov %cr0,%eax + or $X86_CR0_PE,%al + mov %eax,%cr0 + + // Long jump into protected mode + // Hardcode the address + ljmpl $0x8,$0x400000 + + // Loader GDT and GDTR + .align(16) + .global loader_gdt +loader_gdt: + .quad 0 + .quad 0x00cf9a000000ffff + .quad 0x00cf92000000ffff + +loader_gdt_ptr: + .short loader_gdt_ptr - loader_gdt - 1 + .long loader_gdt + + .size __reset_entry, . - __reset_entry + /**************************************************************************** * .text @@ -124,6 +156,11 @@ header_end: * ****************************************************************************/ +start32_0: + mov $0x10, %ax + mov %ax, %ss + mov %ax, %ds + .type __pmode_entry, @function __pmode_entry: start32: diff --git a/boards/x86_64/intel64/qemu-intel64/scripts/qemu.ld b/boards/x86_64/intel64/qemu-intel64/scripts/qemu.ld index b5848241d1..9be191c362 100644 --- a/boards/x86_64/intel64/qemu-intel64/scripts/qemu.ld +++ b/boards/x86_64/intel64/qemu-intel64/scripts/qemu.ld @@ -22,12 +22,20 @@ OUTPUT_ARCH(i386:x86-64) ENTRY(__pmode_entry) SECTIONS { + + . = 0x0; + + .realmode : { + . = ALIGN(8); + KEEP(*(.multiboot)) + *(.realmode) + } + . = 0x1M; _kernel_physical_start = .; .loader.text : { . = ALIGN(8); - KEEP(*(.multiboot)) *(.loader.text) }