I need to add an own system call to the Raspbian Linux Kernel. Now I am stuck after searching for about 2 days to find a solution.
To add a system call, I am basically following the general outline (http://elinux.org/RPi_Kernel_Compilation) using the kernel sources from the following git repo:
git://github.com/raspberrypi/tools.git
I have installed a cross-compile environment using crosstool-ng (http://www.kitware.com/blog/home/post/426).
All these above works. I am able to compile and deploy a new kernel. I am furthermore able to cross-compile for the Raspbian.
I am trying to add a 'hello world' system call. The function resides in its own implementation files (kernel/helloworld.?) and are implemented as:
helloworld.c:
#include <linux/linkage.h>
#include <linux/kernel.h>
#include <linux/random.h>
#include "helloworld.h"
asmlinkage long sys_helloworld(){
printk (KERN_EMERG "hello world!");
return get_random_int()*4;
}
helloworld.h:
#ifndef HELLO_WORLD_H
#define HELLO_WORLD_H
asmlinkage long sys_helloworld(void);
#endif
The Makefile is extended accordingly.
I am now stuck in the error message
AS arch/arm/kernel/entry-common.o
arch/arm/kernel/entry-common.S: Assembler messages:
arch/arm/kernel/entry-common.S:104: Error: __NR_syscalls is not equal to the size of the syscall table
make[1]: *** [arch/arm/kernel/entry-common.o] Error 1
By following the advice in Writing a new system call, I added the following:
arch/arm/kernel/calls.S
CALL(sys_helloworld)
arch/arm/include/uapi/asm/unistd.h
#define __NR_helloworld (__NR_SYSCALL_BASE+380)
include/uapi/asm-generic/unistd.h
#define __NR_helloworld 274 __SYSCALL(__NR_helloworld, sys_helloworld) #define __NR_syscalls 275
arch/x86/syscalls/syscall_32.tbl
351 i386 helloworld sys_helloworld
I am now stuck in solving the error.
When removing the line in calls.S, the kernel compiles fine; though I can't invoke the system call. When adding the line stated above, I am getting the mentioned error.
For reference: The client-code for testing the system call is:
#include <linux/unistd.h>
#include <stdio.h>
#include <sys/syscall.h>
int main (int argc, char* argv[])
{
int i=atoi(argv[1]);
int j=-1;
printf("invocing kernel function %i\n", i);
j=syscall(i); /* 350 is our system calls offset number */
printf("invoked. Return is %i. Bye.\n", j);
return 0;
}
All other system calls (e.g., 1 == sys_exit) work fine.
Any ideas what I am missing? E.g., I don't fully get how to implement rasens answer.