Reputation: 707
Interestingly, I couldn't find any simple example on web. Can you share a simple example please? I'm trying to understand following by analyzing an example.
⦁ Typically,
⦁ a number associated with each system call
⦁ Number used as an index to a table: System Call table
⦁ Table keeps addresses of system calls (routines)
⦁ System call runs and returns
⦁ Caller does not know system call implementation
⦁ Just knows interface
Upvotes: 2
Views: 5160
Reputation: 1616
This depends on which architecture you want to add a system call for, or if you want to add the system call for all architectures. I will explain one way to add a system call for ARM.
mysyscall
.Choose a syscall number. In arch/arm/include/asm/unistd.h
, take note of how each syscall has a specific number (__NR__SYSCALL_BASE+<number>
) assigned to it. Choose an unused number for your syscall. Let us choose syscall number 223. Then add:
#define __NR_mysyscall (__NR_SYSCALL_BASE+223
where the index 223 would be in that header file. This assigns the number 223 to your syscall on ARM architectures.
Modify architecture-specific syscall table. In linux/arch/arm/kernel/calls.S
, change the line that corresponds to syscall 223 to:
CALL(sys_mysyscall)
Add your function prototype. Suppose you wanted to add a non-architecture-specific syscall. Edit the file: include/linux/syscalls.h
and add your syscall's prototype:
asmlinkage long sys_mysyscall(struct dummy_struct *buf);
If you wanted to add it specifically for ARM, then do the following except in this file: arch/arm/kernel/sys_arm.c
.
Implement your syscall somewhere. Create a file whereever you please. For example, in the kernel/
directory. You need to at least have:
#include <linux/syscalls.h>
...
SYSCALL_DEFINE1(mysyscall, struct dummy_struct __user *, buf)
{
/* Implement your syscall */
}
Note the macro, SYSCALL_DEFINE1
. The number at the end should correspond to how many input parameters your syscall has. In this case, our system call only has 1 parameter, so you use SYSCALL_DEFINE1
. If it had two parameters, you would use SYSCALL_DEFINE2
, etc.
Don't forget to add the object (.o) file to the Makefile in the directory where you put it.
mysyscall()
. You need to use the syscall()
function which takes a system call number as its first argument:struct dummy_struct *buf = calloc(1, sizeof(buf));
int res = syscall(223, buf);
Do note that this was for ARM. The process will be very similar for other architectures.
Edit: Don't forget to add your syscall file to the Makefile in kernel/.
Upvotes: 9