Jumping to IA-32e / Long mode

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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.

[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux