Adding a Linux system call
|
System call demultiplexing
Some system calls are further demultiplexed by the kernel. For example, the Berkeley Software Distribution (BSD) socket calls (socket , bind , connect , and so on) are associated with a single system call index (__NR_socketcall ) but are demultiplexed in the kernel to the appropriate call through another argument. See ./linux/net/socket.c function sys_socketcall .
|
|
Adding a new system call is mostly procedural, although you should look out for a few things. This section walks through the construction of a few system calls to demonstrate their implementation and use by a user-space application.
You perform three basic steps to add a new system call to the kernel:
- Add the new function.
- Update the header files.
- Update the system call table for the new function.
Note: This process ignores user-space needs, which I address later.
Most often, you create a new file for your functions. However, for the sake of simplicity, I add my new functions to an existing source file. The first two functions, shown in Listing 1, are simple examples of a system call. Listing 2 provides a slightly more complicated function that uses pointer arguments.
Listing 1. Simple kernel functions for the system call example
asmlinkage long sys_getjiffies( void )
{
return (long)get_jiffies_64();
}
asmlinkage long sys_diffjiffies( long ujiffies )
{
return (long)get_jiffies_64() - ujiffies;
}
|
In Listing 1, two functions are provided for jiffies monitoring. (For more information about jiffies, see the sidebar, "Kernel jiffies.") The first function returns the current jiffies, while the second returns the difference of the current and the value that the caller passes in. Note the use of the asmlinkage
modifier. This macro (defined in linux/include/asm-i386/linkage.h) tells the compiler to pass all function arguments on the stack.
Listing 2. Final kernel function for the system call example
asmlinkage long sys_pdiffjiffies( long ujiffies,
long __user *presult )
{
long cur_jiffies = (long)get_jiffies_64();
long result;
int err = 0;
if (presult) {
result = cur_jiffies - ujiffies;
err = put_user( result, presult );
}
return err ? -EFAULT : 0;
}
|
共8页: 上一页 [1] 2 [3] [4] [5] [6] [7] [8] 下一页