With the first method, you call your new functions as identified by their index through the syscall function. With the syscall function, you can call a system call by specifying its call index and a set of arguments. For example, the short application shown in Listing 5 calls your sys_getjiffies using its index.
Listing 5. Using syscall to invoke a system call
#include <linux/unistd.h>
#include <sys/syscall.h>
#define __NR_getjiffies 320
int main()
{
long jiffies;
jiffies = syscall( __NR_getjiffies );
printf( "Current jiffies is %lx\n", jiffies );
return 0;
}
|
As you can see, the syscall function includes as its first argument the index of the system call table to use. Had there been any arguments to pass, these would be provided after the call index. Most system calls include a SYS_ symbolic constant to specify their mapping to the __NR_ indexes. For example, you invoke the index __NR_getpid with syscall as:
The syscall function is architecture specific but uses a mechanism to transfer control to the kernel. The argument is based on a mapping of __NR indexes to SYS_ symbols provided by /usr/include/bits/syscall.h (defined when the libc is built). Never reference this file directly; instead use /usr/include/sys/syscall.h.
The traditional method requires that you create function calls that match those in the kernel in terms of system call index (so that you're calling the right kernel service) and that the arguments match. Linux provides a set of macros to provide this capability. The _syscallN macros are defined in /usr/include/linux/unistd.h and have the following format:
_syscall0( ret-type, func-name )
_syscall1( ret-type, func-name, arg1-type, arg1-name )
_syscall2( ret-type, func-name, arg1-type, arg1-name, arg2-type, arg2-name )
|
![](/upimg/allimg/070327/1729014.gif) |
User-space and __NR constants
Note that in Listing 6 I've provided the __NR symbolic constants. You can find these in /usr/include/asm/unistd.h (for standard system calls).
|
|
The _syscall macros are defined up to six arguments deep (although only three are shown here).
Now, here's how you use the _syscall macros to make your new system calls visible to the user-space. Listing 6 shows an application that uses each of your system calls as defined by the _syscall macros.
Listing 6. Using the _syscall macro for user-space application development
#include <stdio.h>
#include <linux/unistd.h>
#include <sys/syscall.h>
#define __NR_getjiffies 320
#define __NR_diffjiffies 321
#define __NR_pdiffjiffies 322
_syscall0( long, getjiffies );
_syscall1( long, diffjiffies, long, ujiffies );
_syscall2( long, pdiffjiffies, long, ujiffies, long*, presult );
int main()
{
long jifs, result;
int err;
jifs = getjiffies();
printf( "difference is %lx\n", diffjiffies(jifs) );
err = pdiffjiffies( jifs, &result );
if (!err) {
printf( "difference is %lx\n", result );
} else {
printf( "error\n" );
}
return 0;
}
|
共8页: 上一页 [1] [2] [3] [4] 5 [6] [7] [8] 下一页 |