Page 1 of 1
System API abstraction question
Posted: Thu Jan 21, 2010 8:38 pm
by neon
Hello everyone,
This is a design question. The system API can be called upon in my system by using a software interrupt and passing a function identifier in eax. I was thinking of abstracting this behind a dynamic library API for user mode software.
For example, instead of a program having to set up registers and call the system interrupt directly, it can just use the C API library and do something like
sysopen() which will set everything up.
The method seems to be very clean but I want to get some feedback on the idea. The problem that I see is that most of the routines will just be one liners like this:
Code: Select all
//NtSystemRequest puts the parameters in the registers and calls the system software interrupt that will call the correct kernel mode function
int
NtBrk (DWORD EndDataSegment) {
return NtSystemRequest (SYSTEM_CALL_BRK, EndDataSegment, 0, 0);
}
//100 some other routines might be like this... o_o
What do you think of the idea? Any comments? Should I go for it?
Re: System API abstraction question
Posted: Thu Jan 21, 2010 8:46 pm
by thepowersgang
... this is what usually happens.
Most OSs will have a library called libthisos.so (or something like that, I have libacess.so) that abstracts the systemcalls out from mov eax, CALL; int 0xXX to a C function, usually by using inline assembler.
Int the example you provided, NtSystemRequest would probably be either a macro, or an assembly function that calls the system call in a clean way.
Re: System API abstraction question
Posted: Thu Jan 21, 2010 8:51 pm
by neon
thepowersgang wrote:... this is what usually happens.
Oh. I knew Windows did it (Didnt know Linux also), it just seems .. long-winded. ie, having 100-200 some one liner routines.
Thanks for your suggestion
Re: System API abstraction question
Posted: Fri Jan 22, 2010 12:50 am
by bitshifter
Alernatively you could have a call-table.
Which user app can use int to fill local table.
DexOS use this method.
There is a trade-off between size and speed.
You want it to be small or fast?
Re: System API abstraction question
Posted: Fri Jan 22, 2010 3:00 am
by Grunt
bitshifter wrote:Alernatively you could have a call-table.
This is not about how you implement system calls, but wrapping them.
I would use #defines, but that's just personal preference.
Re: System API abstraction question
Posted: Fri Jan 22, 2010 4:01 am
by qw
You could implement several layers and use the layer that meets your needs best in a certain situation.
For example, you could use INT, SYSCALL, or SYSENTER in raw assembly if speed is your main concern. Then you could use NtSystemRequest() as a wrapper in C for OS-specific code. On top of that a POSIX-style function like open() that calls NtSystemRequest(SYSTEM_CALL_OPEN, ...) and on top of that the ISO C function fopen() that calls open().
This way the design is the cleanest, I think.
Roel
EDIT: NtSystemRequest() could choose to use INT, SYSCALL, or SYSENTER at run time.
Re: System API abstraction question
Posted: Fri Jan 22, 2010 10:45 am
by Love4Boobies
Probably has the most overhead too.
Re: System API abstraction question
Posted: Fri Jan 22, 2010 3:43 pm
by neon
Hello,
Love4Boobies wrote:Probably has the most overhead too.
That is what I am worried about. Grunt's method would certainly solve that issue but at the cost of user mode software having to be compiled with the system API #defines.
With my current method, Im going to be ending up with a library filled with 100-200 some one-liner routines calling NtSystemRequest. I suppose it wont be that bad if NtSystemRequest is inline though.
I appreciate the suggestions
Re: System API abstraction question
Posted: Sat Jan 23, 2010 5:04 pm
by FlashBurn
The library has also one advantage over the defines which every user code would use. If you change something with you System API, the programs wills till work, because all you need to do is change this library. But this also works just if you neednĀ“t one more parameter.
Re: System API abstraction question
Posted: Mon Jan 25, 2010 3:54 pm
by inx
Personally, I use a jump table because one of my goals in my system is to, at least mostly, keep binary compatibility between revisions on the same architecture. I have different jump tables for SYSCALL/SYSRET, SYSENTER/SYSEXIT, and INT calls, and just choose which to use at boot and map it into the top of each process's address space. My syscall.h is just a bunch of function pointers that point to the right offsets in the jump table.