Fast system calls with SYSENTER and SYSEXIT

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
XCHG
Member
Member
Posts: 416
Joined: Sat Nov 25, 2006 3:55 am
Location: Wisconsin
Contact:

Fast system calls with SYSENTER and SYSEXIT

Post by XCHG »

Has anybody made fast system calls with SYSENTER and SYSEXIT from DPL0 to DPL0? Is this possible? If not, what is the fastest way of making system calls from DPL0 to DPL0.
On the field with sword and shield amidst the din of dying of men's wails. War is waged and the battle will rage until only the righteous prevails.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

If you're doing kernel->kernel calls (which is what you say), just use normal function calls, no?

sysenter/syscall are for ring 3 <-> ring 0 exclusively.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
bewing
Member
Member
Posts: 1401
Joined: Wed Feb 07, 2007 1:45 pm
Location: Eugene, OR, US

Post by bewing »

Yeah, your kernel (or whatever) needs to export its entrypoints -- usually by writing them to a table at a known memory location. Then you call the entrypoint from the other ring0 app.

Code: Select all

free		equ	0x20000c

	call [free]
Ready4Dis
Member
Member
Posts: 571
Joined: Sat Nov 18, 2006 9:11 am

Post by Ready4Dis »

Yeah, as said above, it's just a regular function call since it's in the same ring. My drivers and kernel reside in the same ring, and I link my drivers to the kernel when they are loaded to link symbolic information (I use coff files, but a.out, elf, pe are other commonly used variants), or as stated, use a known location to generate a table (my old way I did it). Basically, set aside a block of memory to hold function pointers... so, for example... a viod SayHi(char *Say); function :).

You reserve a known address space (we'll even forget about paging right now since it's outside the scope of this discussion), lets say we want our function table to be at 0x1000, or the first 4k page boundary. Would would simply do this in the kernel:

Code: Select all

u32 *FuncTable = 0x1000;

void SayHi(char *Say)
{
 kprintf("SayHi: %s\n",Say); //Print the string passed for testing
}

void SetFuncPointer(void *Func, unsigned long FunctionNumber)
{
  FuncTable[FunctionNumber] = (u32)Func;
}

void InitFuncs(void)
{
 SetFuncPointer(SayHi,0); //first function
}
now for your driver/application to find the function for SayHi, it knows that it is function 0... so..

Code: Select all

u32 FuncTable = (u32*)0x1000;

void *GetFuncPointer(u32 FunctionNumber)
{
 return (void*)FuncTable[FunctionNumber];
}

void (*SayHi)(char *Say);
void InitKernelFuncs(void)
{
 SayHi = (void(*)(char*))GetFuncPointer(0);
}
So, now your application knows that the location of the function SayHi is the first entry in the table @ 0x1000, so it can call it without any extra information once the function pointer is set at the correct place. I typed it all in this window, so maybe a casting error or similar, but it should give you the idea on what's going on.
Post Reply