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.
--> I got this working. The permission bit in PDT and PDPT were not right
although they _were_ identity mapped.

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
--> This step had to be done after we switch to 64-bit mode.

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.

Reply via email to