PDA

View Full Version : System call



DBQ
September 22nd, 2007, 07:54 AM
Hey guys. I am trying to implement a system call in linux kernel. I usually use ubutntu, but this I am doing on Fedora. I am using kernel 2.6. Here is what I did:

1. Added a line to arch/i386/kernel/syscall_table.S:

.long sys_foo

2. Added a line to linux/include/asm-i386/unistd.h:

#define __NR_foo 324

also incremented the call count by 1.

3. Added this code to sys.c



asmlinkage long sys_foo(void)
{
printk("Hello Kernel World");
return THREAD_SIZE;
}
[\code]

4. Wrote this user level client program to test my call:

[code]
#include <unistd.h>
#include <linux/unistd.h>


#define __NR_foo 324
__syscall0(long, foo)

int main()
{

foo();
return 0;
}



However, when I compile the user level program, I get the following error:

test.c:6: error: expected declaration specifiers or ‘...’ before ‘foo’
test.c: In function ‘__syscall0’:
test.c:9: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘{’ token
test.c:6: error: parameter name omitted
test.c:13: error: expected ‘{’ at end of input

Anybody has any idea?

gnusci
September 22nd, 2007, 12:10 PM
I really did not check very deeply your problem, but from the error output I think you are missing a ";", and I guess is after:



#include <unistd.h>
#include <linux/unistd.h>

#define __NR_foo 324
__syscall0(long, foo); <---- HERE

int main()
{

foo();
return 0;
}

DBQ
September 22nd, 2007, 07:30 PM
I actually followed one of the examples. And the examle did not have the semicolon. Plus __syscall is a macro, and it does not require the ;. What else could it be?

gnusci
September 22nd, 2007, 09:38 PM
Ok, another possible cause of problems, here the notes:



#include <unistd.h>
//#include <linux/unistd.h> // <--- the first one is enough


#define __NR_foo 324
_syscall0(long, foo) // <---- Use just one underscore

int main()
{

foo();
return 0;
}


You also may need to include #include<linux/linkage.h> into sys.c in order to use asmlinkage.



#include<linux/linkage.h>

asmlinkage long sys_foo(void)
{
printk("Hello Kernel World"); //<--- printf()
return THREAD_SIZE;
}


Here a tutorial:

http://tldp.org/HOWTO/html_single/Implement-Sys-Call-Linux-2.6-i386/

DBQ
September 22nd, 2007, 10:28 PM
Hey. I tried your suggestions except the printf one. Using printf is never allowed in the kernel land. However, the error message persists.
Any other ideas? Thanks for your support.

gnusci
September 23rd, 2007, 01:35 PM
Hey. I tried your suggestions except the printf one. Using printf is never allowed in the kernel land. However, the error message persists.
Any other ideas? Thanks for your support.

Did you review all the steps in the tutorial above, specially step number 17

17. Testing our new system call

vartak_kedar
September 30th, 2007, 02:48 AM
Hi,

I was writing a system call after following the link
http://tldp.org/HOWTO/Implement-Sys-Call-Linux-2.6-i386/index.html

But then I am getting same error messages when I compile my test program to check whether my system call is working.

I have followed the steps exactly as given in the document, only instead of foo call I have used my xtime call with timespec structure.

I am getting the same error messages. It has been mentioned that the _syscall1/_syscall0 macros are defined in the unistd.h file but I dont find them there.

Help needed...

Thanks
Kedar

LordShadow
October 4th, 2007, 08:40 PM
Just try to compile your test program with the -D __KERNEL__ option (2 underscores before and after KERNEL). It should be something like:

gcc -D __KERNEL__ -o foo foo.c

regmee
August 21st, 2008, 11:14 PM
(i will reply though the thread is very old)

"man _syscall"
This will tell u that after kernel 2.6.18, the _syscall macros were removed from header files supplied to user space.

You need to use syscall() instead.


eg:

#define __NR_sys_silly_copy 327

len_bytes_copied = syscall(__NR_sys_silly_copy, &temp, &dst, sizeof(unsigned long));



-regmee