GNU Assembler - Enter Long Mode
Posted: Tue May 21, 2013 5:49 am
Hello,
I need help, I want to switch to long mode using GNU Assembler. I'm stuck setting up the different page tables. I saw an example, but it is in Intel Assembly. Can anyone explain me how to proceed, please?
Here is the example: (I don't know what exectly what he is doing between enabling physical-address extensions and loading page-map level-4 base)
http://board.flatassembler.net/topic.php?t=6206
Here is my code: (I am stuck within "load CR3 with PML4" part)
Thank you for any useful help!
I need help, I want to switch to long mode using GNU Assembler. I'm stuck setting up the different page tables. I saw an example, but it is in Intel Assembly. Can anyone explain me how to proceed, please?
Here is the example: (I don't know what exectly what he is doing between enabling physical-address extensions and loading page-map level-4 base)
http://board.flatassembler.net/topic.php?t=6206
Here is my code: (I am stuck within "load CR3 with PML4" part)
Code: Select all
INITSEG = 0x0050
INITOFF = 0x0000
.section .rodata
gdt:
# Null Descriptor
.word 0x0000, 0x0000
.byte 0x00, 0b00000000, 0b00000000, 0x00
# Code Descriptor
.word 0xffff, (INITSEG * 0x10 + INITOFF)
.byte 0x00, 0b10011010, 0b11001111, 0x00
# Data Descriptor
.word 0xffff, (INITSEG * 0x10 + INITOFF)
.byte 0x00, 0b10010010, 0b11001111, 0x00
gdt_end:
gdt32ptr:
.word (gdt_end - gdt - 1)
.long (gdt + INITSEG * 0x10 + INITOFF)
gdt64ptr:
.word (gdt_end - gdt - 1)
.quad (gdt + INITSEG * 0x10 + INITOFF)
.section .text
.globl Start
Start:
.code16
# Load Global Descriptor Table
lgdt gdt32ptr
# Load Control Register CR0
# Enable Protected Mode (Bit0 in CR0)
# Store Control Register CR0
movl %cr0, %eax
orl $(1<<0), %eax
movl %eax, %cr0
# Setup all Segment Registers
# and reload Code Segment, Instruction Pointer
movw $0x0010, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %fs
movw %ax, %gs
movw %ax, %ss
ljmp $0x0008, $JumpToPM
JumpToPM:
.code32
# Load Control Register CR4
# Enable Physical Address Extension (Bit5 in CR4)
# Store Control Register CR4
movl %cr4, %eax
orl $(1<<5), %eax
movl %eax, %cr4
#----------------- load CR3 with PML4 -----------------------------------------------
movl $0x8000, %edi
movl $0x0100, %ecx
PT:
movw 0x0000, %ax
pushw %ax
loop PT
# movl PML4, %eax
# movl %eax, %cr3
#----------------- load CR3 with PML4 -----------------------------------------------
# Use Model Specific Register 0xC0000080
# Read from Model Specific Register
# Enable Long Mode (Bit8)
# Write to Model Specific Register
movl $0xc0000080, %ecx
rdmsr
orl $(1<<8), %eax
wrmsr
#----------------- halt, next instruction triple faults -----------------------------------------------
hlt
#----------------- halt, next instruction triple faults -----------------------------------------------
# Load Control Register CR0
# Enable Paging (Bit31 in CR0)
# Store Control Register CR0
movl %cr0, %eax
orl $(1<<31), %eax
movl %eax, %cr0
.code64
# Reload Global Descriptor Table
lgdt gdt64ptr
# Enter into the kernel
call kmain
Hang:
# Halt the CPU
# Infinit loop if Halt doesn't work
hlt
jmp Hang