User side of system calls

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
justin
Member
Member
Posts: 43
Joined: Sun Jan 11, 2009 2:09 pm

User side of system calls

Post by justin »

How do you implement system calls on the user's end? I was going to borrow the linux _syscall macros which a copied from an old unistd.h:

Code: Select all

#define _syscall0(type,name) \
type name(void) \
{ \
long __res; \
__asm__ volatile ("int $0x80" \
	: "=a" (__res) \
	: "0" (__NR_##name)); \
if (__res >= 0) \
	return (type) __res; \
errno = -__res; \
return -1; \
}
But I'm not getting it to compile and I was wondering if there is a better way.
AndrewBuckley
Member
Member
Posts: 95
Joined: Thu Jan 29, 2009 9:13 am

Re: User side of system calls

Post by AndrewBuckley »

code seems strait forward to me. but it only works if your syscall interface works the same.

1)the code calls int 0x80 (linux syscall)
2)checks the result if its a positive number. if positive or 0 things went well return result.
if negative there was an error. set errno the value given as a positive number, and return -1.

at the very least errno must be defined somewhere.
you should understand what code does before you try to use it.
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: User side of system calls

Post by bluemoon »

justin wrote:How do you implement system calls on the user's end?
My 32-bit kernel uses INT 80 style syscall, where eax=function number, ebx, ecx, edx, esi, edi can be used as #1, #2, #3... parameters. return value are returned with eax, edx(2nd return)

For example:

Code: Select all

section .text
; ----------------------------------------------
; int _exit (int exit_code);
_exit:
    push    ebx
    mov     eax, 1
    mov     ebx, [esp+8]
    int     0x80
    pop     ebx
    ret

; ----------------------------------------------
; int open ( const char * file, int flags, int mode );
open:
    push    ebx
    push    ecx
    push    edx
    mov     ebx, [esp+16]   ; file
    mov     ecx, [esp+20]   ; flags
    mov     edx, [esp+24]   ; mode
    mov     eax, 2
    int     0x80
    pop     edx
    pop     ecx
    pop     ebx
    ret
I'm currently working on 64-bit kernel and plan to use syscall/sysret instead of INT, they should be quite simular using registers for communication.
justin
Member
Member
Posts: 43
Joined: Sun Jan 11, 2009 2:09 pm

Re: User side of system calls

Post by justin »

Merlin wrote:code seems strait forward to me. but it only works if your syscall interface works the same.

1)the code calls int 0x80 (linux syscall)
2)checks the result if its a positive number. if positive or 0 things went well return result.
if negative there was an error. set errno the value given as a positive number, and return -1.

at the very least errno must be defined somewhere.
you should understand what code does before you try to use it.
I understand what it does. That's not the problem.
justin
Member
Member
Posts: 43
Joined: Sun Jan 11, 2009 2:09 pm

Re: User side of system calls

Post by justin »

I ran gcc -E on my source file and apparently the preprocessor is not expanding the _SYSCALL0 macro.

I have this in my source file:

Code: Select all

int errno;
_SYSCALL0(int,endthread)
I include a file with:

Code: Select all

#define __NR_endthread	0x1

extern int errno;

#define _syscall0(type,name) \
type name(void) \
{ \
long __res; \
__asm__ volatile ("int $0x40" \
	: "=a" (__res) \
	: "0" (__NR_##name)); \
if (__res >= 0) \
	return (type) __res; \
errno = -__res; \
return -1; \
}
and then I get these errors:

Code: Select all

thread.c:299: error: expected declaration specifiers or ‘...’ before ‘endthread’
cc1: warnings being treated as errors
thread.c:299: error: return type defaults to ‘int’
thread.c: In function ‘_SYSCALL0’:
thread.c:299: error: parameter name omitted
thread.c:299: error: expected ‘{’ at end of input
Anybody know why the macro might not work?
justin
Member
Member
Posts: 43
Joined: Sun Jan 11, 2009 2:09 pm

Re: User side of system calls

Post by justin »

I see it now, I wrote SYSCALL when it is syscall.
User avatar
AndrewAPrice
Member
Member
Posts: 2303
Joined: Mon Jun 05, 2006 11:00 pm
Location: USA (and Australia)

Re: User side of system calls

Post by AndrewAPrice »

Link with a syscall library and upon your first system call all of your functions jump to a handler that detect if the CPU supports sysenter, syscall, or fallback to int. Then overwrite each of the syscall functions with the most optimal handler for that CPU.
My OS is Perception.
Post Reply