Hello,
I'm working on a 32-bit BIOS program for some embedded system with 64-bit CPU and I'm trying to test 64-bit mode. The BIOS normally runs in 32-bit mode. It, however, needs to performs some test for the 64-bit mode. So the drill is to jump to Long mode, perform some test (for now, I just want to print a character) and jump back to 32-bit mode.
The Problem:
For compatibility reasons, I _cannot_ compile the BIOS to be elf64 along with 64-bit test code to link them together to create binary image. So I _have_ to compile BIOS to elf32 and still be able to call 64-bit code and resume running 32-bit code on return.
The Solution:
that I've approached is to run 64-bit code as stream of binary bytes. (I compile 64-bit code using 64-bit NASM to _binary_ file separately to produce hex code). For example,
char hexcode[] = "\xba\xf8\x03\x00\x00"; // this is arbitrary code
void (*fptr)(void);
fptr = (void (*)(void)) hexcode;
(*fptr)();
For this solution, the code has to Position Independent and I use techniques to write shellcode (as demonstrated here http://www.safemode.org/files/zillion/shellcode/doc/Writing_shellcode.html) to make sure of that.
I'm following steps as followed:
(At the point when I execute this code, GDT is setup with entry (also) for 64-bit CS/DS discriptors, the PE = 1 (protected mode enabled) and PG = 0 (paging disabled))
C - 1) Setup PML4 pages (these are identity mapped.. for sure) and load cr3.
C - 2) Setup new IDT for 64-bit mode
ASM32 - 3) Disable Interrupts
ASM32 - 4) Install IDT that was setup in step-2
ASM32 - 5) Setup all data-segment registers (ds, es, fs, gs, ss) to point to 64-bit DS Descriptor
ASM32 - 6) Enable PAE mode
ASM32 - 7) Enable Long mode
ASM32 - 8) Turn on Paging (this is the last step that does the transition to 64-bit mode)
ASM32 - 9) Far jump to 64-bit code
ASM64 - 10) Print a Character
ASM64 - 10) return
Currently, I'm just testing code _only_ to transition to IA-32e mode and not to jump back to 32-bit mode. I've some mechanism through which I can confirm that the addresses in hexcode are good. I've found out from probing that it fails on step-8 and gets general protection fault. I've tested this code in different order too and it just gets frozen on step-8.
Any idea, what I could be doing wrong? Please help.
Thanks,
/tejas
PS: "C" and "ASM" prefix in steps designates what language the part of the code is written in.