flat assembler
Message board for the users of flat assembler.
Index
> OS Construction > 64 bit to 32 bit jmp problem, |
Author |
|
OS ? 18 Apr 2006, 21:33
Hi lazer1
Just a guess but I think you need to look into page translation? |
|||
18 Apr 2006, 21:33 |
|
MAD_DËMON 19 Apr 2006, 00:24
I think that you need to disable Long Mode Active Bit from the EFER MSR and load the 32 bit legacy GDT before make the jump that transfer the control to a 32 bit pmode
Code: org 10000h use64 lgdt [gdt] jmp far 2:trick32 ; Selector Index 1 : Trick 32 use32 trick32: ; ......... ;============================ GDT =============================== gdt: ;=============== NULL segment ============== .null dd 0 dd 0 ;=========== code32 ================== .code32: dw 0ffffh dw 0h db 0 db 10011110b db 11001111b db 0 ;========================================================= ;........... if it not work then look to the AMD or Intel system programming manuals I think that it can be do making a "Compatibility Mode/Legacy" Code Descriptor in a 64 bit GDT _________________ Tah rah rah boom de ay, I blew some guy away, his brains turned into spray, I was paid well that day |
|||
19 Apr 2006, 00:24 |
|
lazer1 19 Apr 2006, 02:17
OS ? wrote: Hi lazer1 Hi, the above code fragment omits all the stuff to reach 64 bit, I've modified it now so you see what I mean, the question was a compilation question, that fasm doesnt compile the fragment I gave, |
|||
19 Apr 2006, 02:17 |
|
lazer1 19 Apr 2006, 02:34
MAD_DËMON wrote: I think that you need to disable Long Mode Active Bit from the EFER MSR and load the 32 bit legacy GDT before make the jump that transfer the control to a 32 bit pmode Hi, see other reply, the question was not a run time question but a compile time question, the fragment I gave clearly wont run, however it should compile, at least I'm asking what modification of it will compile, I've just tried "far" instead of "pword" and it also doesnt compile, Note that its not 2:some_offset but 2 * 8 : some_offset, and its not in fact 2 but 1 so its 8:some_offset as the GDT index is shifted left 3 bits, ie the GDT index is literally the offset into the GDT table, gdt.code64-gdt achieves this, :useful trick, ie gdt.code64-gdt:some_offset is (index shl 3):some_offset, Quote: ... making a "Compatibility Mode/Legacy" Code Descriptor in a 64 bit GDT you dont need a 64 bit GDT, 64 bit segment descriptors can be put in a 32 bit GDT, thats a useful feature of AMD's design that you dont need a new GDT, and note that 64 bit uses virtually no segment descriptors, and if you try loading ds with one the machine resets, fs and gs are 64 bit in long mode and you load + read them with a msr fs.base and gs.base, ie you dont use the GDT, the GDT is only used for things like switching to compatibility mode and loading the IDT and TR, however I think you do need a new 64 bit IDT, I've not got as far as interrupts yet, long mode is basically an unsegmented architecture, segments are only used mainly to enter and leave long mode, once you are in long mode you dont use segments, which is really great because I hate segments! long mode is always full flat addressing, also long mode has extra 64 bit registers: R8, R9, R10, R11, R12, R13, R14, R15, not just rax, rbx, rcx, rdx, rsi, rdi, rbp, rsp, but you get an extra 8 new GPRs, I've tried a few things with long mode and it is fantastic, eg I set up gs with a 64 bit value, 00000000000B8000h via the msr, and wrote to the screen successfully with this, |
|||
19 Apr 2006, 02:34 |
|
fonolite 19 Apr 2006, 06:45
jmp to compatibility mode is not the change of modes.
It's just a jump between 32bit and 64bit segment. You always should keep EFER.LMA=1 active. This is my code about jmp to 32bit segment. Code: jmp far pword [@F] @@: dd Trick32 dd gdt.code32-gdt ; .code32-gdt value This is indirect jmp far to selector32:offset32 I remember long mode doesn't allow direct jmp as follows. Code: jmp far pword gdt.code32-gdt:trick32 (anyway compiled OK.) |
|||
19 Apr 2006, 06:45 |
|
lazer1 20 Apr 2006, 14:46
Hi fonolite,
your code fragment is excellent it answers the question exactly and the anonymous label trick is a very clean way to keep the code readable, fonolite wrote: jmp to compatibility mode is not the change of modes. technically its just a jmp or a call through the GDT, so its not even supervisor level (I think), it is as powerful as a mode change but isnt a mode change, Quote:
that answers the original question superbly Quote:
with long mode if you do something which would be correct in other modes and it compiles then it tends to be correct in long mode, so far all 64 bit code I've tried that fasm accepts also runs correctly. interrupts are switched off via cli and I cannot access most of ram as the MMU tree is almost empty. Also I switched off all caching to make sure the gfx mem is uncached. I have just enough set up to experiment with things. I dont have any useful code yet and wrote text by hacking it directly: Code: ..... use64 .... ; CPL==0 only: FS.base msr @ is c000_0100h, gs.base msr is c000_0101 mov ecx,0c0000101h ; gs.base mov edx,0 mov eax,0b8000h wrmsr ; edx:eax to msr(ecx) mov [gs:0h], byte 'H' mov [gs:1h], byte 1111001b mov [gs:2h], byte 'A' mov [gs:3h], byte 1111010b mov [gs:4h], byte 'H' mov [gs:5h], byte 1111100b mov [gs:6h], byte 'A' mov [gs:7h], byte 11111b mov [gs:8h], byte 'H' mov [gs:9h], byte 101111b mov [gs:0ah], byte 'A' mov [gs:0bh], byte 1001111b .rpt: jmp .rpt the above functioned correctly echoing HAHAHA to the screen, all my 80x25 text code is in 16 bit real so I cannot use it, it will require some work before I know for sure, but I am confident about your code fragment, I want to try and revert to real mode from long mode as that looks like an interesting problem! once I reach real mode then I'll switch on interrupts and I can use the BIOS, |
|||
20 Apr 2006, 14:46 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.