Long mode basics
- salil_bhagurkar
- Member
- Posts: 261
- Joined: Mon Feb 19, 2007 10:40 am
- Location: India
Long mode basics
Hello.. I currently have my os in pmode. I need to also make it work in long mode. Is it possible that without changing much code other than paging, i can port it to long mode? Where can i get good examples for long mode?
OK, here goes the shortest sample:
You may need tto play with ORG for your loader etc.
PS: Code by Tomasz Grysztar, more examples here: http://board.flatassembler.net/topic.php?t=6206
Code: Select all
ORG 1600h
USE16
cli ; disable the interrupts, just in
; case they are not disabled yet
lgdt [cs:GDTR] ; load GDT register
mov eax,cr0 ; switch to protected mode
or al,1
mov cr0,eax
jmp CODE_SELECTOR:pm_start
NULL_SELECTOR = 0
DATA_SELECTOR = 1 shl 3 ; flat data selector (ring 0)
CODE_SELECTOR = 2 shl 3 ; 32-bit code selector (ring 0)
LONG_SELECTOR = 3 shl 3 ; 64-bit code selector (ring 0)
GDTR: ; Global Descriptors Table Register
dw 4*8-1 ; limit of GDT (size minus one)
dq GDT ; linear address of GDT
GDT rw 4 ; null desciptor
dw 0FFFFh,0,9200h,08Fh ; flat data desciptor
dw 0FFFFh,0,9A00h,0CFh ; 32-bit code desciptor
dw 0FFFFh,0,9A00h,0AFh ; 64-bit code desciptor
USE32
pm_start:
mov eax,DATA_SELECTOR ; load 4 GB data descriptor
mov ds,ax ; to all data segment registers
mov es,ax
mov fs,ax
mov gs,ax
mov ss,ax
mov eax,cr4
or eax,1 shl 5
mov cr4,eax ; enable physical-address extensions
mov edi,70000h
mov ecx,4000h shr 2
xor eax,eax
rep stosd ; clear the page tables
mov dword [70000h],71000h + 111b ; first PDP table
mov dword [71000h],72000h + 111b ; first page directory
mov dword [72000h],73000h + 111b ; first page table
mov edi,73000h ; address of first page table
mov eax,0 + 111b
mov ecx,256 ; number of pages to map (1 MB)
make_page_entries:
stosd
add edi,4
add eax,1000h
loop make_page_entries
mov eax,70000h
mov cr3,eax ; load page-map level-4 base
mov ecx,0C0000080h ; EFER MSR
rdmsr
or eax,1 shl 8 ; enable long mode
wrmsr
mov eax,cr0
or eax,1 shl 31
mov cr0,eax ; enable paging
jmp LONG_SELECTOR:long_start
USE64
long_start:
mov rax,'L O N G '
mov [0B8000h],rax
jmp long_start
PS: Code by Tomasz Grysztar, more examples here: http://board.flatassembler.net/topic.php?t=6206
Re: Long mode basics
Hi,
The task switch code needs to change (more registers to save/restore). There's also a few differences with interrupt handling. The code that starts processes may also need changing.
The rest of your code will mostly depend on what language it is. For high level languages you should be able to recompile the code and get it running if it was written as portable code to begin with.
For most assembly code you must change some things to suit (make any addressing 64-bit, remove "PUSHAD", "POPAD", "INC reg" and "DEC reg" instructions, etc) and you will probably want to rewrite everything to use the extra registers.
For the OS design, you may want to change some things depending how they're done now. For example, if you originally made some design decisions based on the amount of linear address space you had to work with, then you might want to redesign those parts now that the there's a huge amount of linear address space.
Also, if you've already got a 32-bit OS then you might want to add support for running 32-bit processes. This should be relatively easy (if applications never have direct access to kernel data structures and don't work with 32-bit physical addresses), but will mean having 2 different kernel APIs. The best way is to make the kernel APIs as similar as possible, so that the 32-bit kernel API is just a small layer over the 64-bit kernel functions.
@Dex: That's not the shortest "switch from real mode to long mode" code possible - you can switch directly from real mode to long mode without any intermediate 32-bit protected mode.
Cheers,
Brendan
You would need to change the paging code because long mode uses 4 levels of paging structures - PML4 (page-map level 4), PDP (page directory pointer table), PD (page directory) and PT (page table). Each of these tables is 4 KB and contains 512 entries that are 8 bytes each.salil_bhagurkar wrote:Hello.. I currently have my os in pmode. I need to also make it work in long mode. Is it possible that without changing much code other than paging, i can port it to long mode? Where can i get good examples for long mode?
The task switch code needs to change (more registers to save/restore). There's also a few differences with interrupt handling. The code that starts processes may also need changing.
The rest of your code will mostly depend on what language it is. For high level languages you should be able to recompile the code and get it running if it was written as portable code to begin with.
For most assembly code you must change some things to suit (make any addressing 64-bit, remove "PUSHAD", "POPAD", "INC reg" and "DEC reg" instructions, etc) and you will probably want to rewrite everything to use the extra registers.
For the OS design, you may want to change some things depending how they're done now. For example, if you originally made some design decisions based on the amount of linear address space you had to work with, then you might want to redesign those parts now that the there's a huge amount of linear address space.
Also, if you've already got a 32-bit OS then you might want to add support for running 32-bit processes. This should be relatively easy (if applications never have direct access to kernel data structures and don't work with 32-bit physical addresses), but will mean having 2 different kernel APIs. The best way is to make the kernel APIs as similar as possible, so that the 32-bit kernel API is just a small layer over the 64-bit kernel functions.
@Dex: That's not the shortest "switch from real mode to long mode" code possible - you can switch directly from real mode to long mode without any intermediate 32-bit protected mode.
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Re: Long mode basics
Thanks for the info Brendan, but the shortest is ment, as in the shortest of the two examples (There's another in the link).Brendan wrote: @Dex: That's not the shortest "switch from real mode to long mode" code possible - you can switch directly from real mode to long mode without any intermediate 32-bit protected mode.
Cheers,
Brendan