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.
_NR_syscalls
defined in arch/arm/include/asm/unistd.h
file this value will always be __NR_last_syscall+1
. Hence in your case _NR_syscalls
should be modified to 381, but this change will also give the same error because of padding in syscall table. Hence define it to 384. This slove the compilation error. Below changes are not necessary:
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
来源:https://stackoverflow.com/questions/21554267/extending-the-rasbian-kernel-linux-kernel-3-10-28-for-arm-raspberry-pi-how