Owen wrote:far return also works to my knowledge (Checking the AMD manuals, it doesn't say anywhere it shouldn't)
gerryg400 wrote:
...
- gerryg400
According to AMD64 Architecture Programmer's Manual Volume 2: System Programming, section 2.5.10, it is illegal to use the far jump instruction in 64-bit mode.
proxy wrote:traditionally in protected mode, after my lgdt, I would do something like (from memory, might be not exactly right)
. Unfortunately, this is not available in long mode. So what is the correct way to do that? I've tried something like this with no success (bochs shows an exception on the ljmp instruction).
The
only correct way to reload the segment registers after you executed the LGDT-instruction in 64-bit mode is to use IRETQ for the code segment register (and perhaps stack segment register, although the latter is useless) and MOV for the other segment registers (DS, ES, FS and GS, although useless as well).
This is some code coming from my 64-bit kernel which works properly (Note: I also modify the RFLAGS, so you might want to look up what bits I'm changing so you get why I am doing this, since this is required in some cases):
Code: Select all
lgdt [GDT.Pointer]
mov rbp, rsp
push QWORD GDT.KData
push rbp
pushfq
pushfq
pop rax
and rax, 1111111111111111111111111111111111111111111111101011111011111111b
push rax
popfq
push QWORD GDT.KCode
push QWORD .Flush
iretq
.Flush:
mov ax, GDT.KData
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
Owen wrote:Of course, there is pretty much no reason to reload the GDT in long mode.
There are reasons to reload the GDT. First of all, the GDT you initially get from boot loaders isn't reliable, since you usually don't know where it is and what descriptors it has. Second of all, after enabling long mode your GDT will not be the most-ideal setup at all so you will want to reload the GDT with one that has a supervisor code entry, a supervisor data entry, a user code entry, a user data entry and a TSS entry or whatever entries you want to have in your GDT (in which case the two different data segments are actually not playing a role and are only there to remain "compatible" with 32-bit mode, since the data descriptors are almost entirely ignored).
Regards,
Stephan J.R. van Schaik.