Entering Long Mode Directly: Difference between revisions

m
Bot: Replace deprecated source tag with syntaxhighlight
[unchecked revision][unchecked revision]
(Fix bugs related to DF)
m (Bot: Replace deprecated source tag with syntaxhighlight)
 
(10 intermediate revisions by 9 users not shown)
Line 1:
For some reason, you might want to switch to 64 bit mode in your bootloader without entering [[protected mode]]. The following article practically described how to do so, mainly demonstrating it by example assembly code. Additionally, some may find it easier to switch directly to long mode on additional CPUs as they are initialized for [[Symmetric Multiprocessing]].
 
== Switching to Long Mode ==
Line 5:
The following can be used to switch directly to Long Mode. The code is well documented through comments, and nearly explains almost everything it does.
 
<sourcesyntaxhighlight lang="asm">
%define PAGE_PRESENT (1 << 0)
%define PAGE_WRITE (1 << 1)
Line 22:
 
; es:edi Should point to a valid page-aligned 16KiB buffer, for the PML4, PDPT, PD and a PT.
; ss:esp Should point to memory that can be used as a small (1 dword uint32_t) stack
 
SwitchToLongMode:
Line 107:
 
.Code:
dq 0x00209800000000000x00209A0000000000 ; 64-bit code descriptor. (exec/read).
dq 0x00009000000000000x0000920000000000 ; 64-bit data descriptor. (read/write).
ALIGN 4
Line 125:
mov fs, ax
mov gs, ax
mov ss, ax
 
; Blank out the screen to a blue color.
mov edi, 0xB8000
mov rcx, 500 ; Since we are clearing QWORDsuint64_t over here, we put the count as Count/4.
mov rax, 0x1F201F201F201F20 ; Set the value to set the screen to: Blue background, white foreground, blank spaces.
rep stosq ; Clear the entire screen.
Line 145 ⟶ 146:
jmp Main.Long ; You should replace this jump to wherever you want to jump to.
</syntaxhighlight>
</source>
 
=== Notes about the above code ===
Line 156 ⟶ 157:
The following example bootsector has been provided for completeness. It checks whether the CPU supports x86_64 or not. It then calls SwitchToLongMode to switch to long mode.
 
<sourcesyntaxhighlight lang="asm">
%define FREE_SPACE 0x9000
 
Line 280 ⟶ 281:
times 510 - ($-$$) db 0
dw 0xAA55
</syntaxhighlight>
</source>
 
 
The above code can be compiled (and tested using QEMU) by the following:
 
<sourcesyntaxhighlight lang="asmbash">
nasm -fbin Main.asm -o LongModeDirectly ;# The main file's name should be Main.asm
qemu-system-x86_64 -hda LongModeDirectly ;# The secondary file's name should be LongModeDirectly.asm and should be in the same directory
</syntaxhighlight>
</source>
 
=== Notes about the above bootsector ===
# The above bootsector has been written just for completeness.
# The above bootsector can't be used as an actual bootsector as it doesn't:
# Enable [[A20]]
# Detect memory
# Load required files from disk using BIOS
 
#* The above bootsector has been written just for completeness.
== See Also ==
#* The above bootsector can't be used as an actual bootsector as it doesn't:
[http://www.osdev.org/phpBB2/viewtopic.php?t=11093 Related forum thread]
# Enable [[A20]]
# Detect memory
# Load required files from disk using BIOS
 
== See Also ==
 
===Forum Threads===
 
* [http://www.osdev.org/phpBB2/viewtopic.php?t=11093 Related forum thread]