Linux Kernel Architecture

(Jacob Rumans) #1

Chapter 13: System Calls


a small number of handler functions are implemented separately for each platform. When results are
returned, the handler function need take no special action; a simplereturnfollowed by a return value is
sufficient. Switching between kernel and user mode is performed by platform-specific kernel code with
which the handler does not come into contact. Figure 13-1 illustrates the chronological sequence.


Application Libc Libc Application

Handler

Kernel Kernel

Userspace Kernelspace Userspace

Figure 13-1: Chronological sequence of a system call.

The above approach greatly simplifies the work of programmers because handler functions are imple-
mented in practically the same way as normal kernel code. Some system calls are so simple that they can
be implemented by a single line of C code. For example, thegetuidsystem call to return the UID of the
current process is implemented as follows:


kernel/timer.c
asmlinkage long sys_getuid(void)
{
/* Only we change this so SMP safe */
return current->uid;
}

currentis a pointer to the current instance oftask_structand is set automatically by the kernel. The
above code returns theuidelement (current user ID) oftask_struct. It couldn’t be simpler!


Of course, there are much more complicated system calls, some of which were discussed in preceding
chapters. Implementation of the handler function itself is always short and compact. It is usual to trans-
fer control to a more general kernel auxiliary function as soon as possible, as, for example, in the case
ofread.


fs/read_write.c
asmlinkage ssize_t sys_read(unsigned int fd, char __user * buf, size_t count)
{
struct file *file;
ssize_t ret = -EBADF;
int fput_needed;

file = fget_light(fd, &fput_needed);
if (file) {
loff_t pos = file_pos_read(file);
ret = vfs_read(file, buf, count, &pos);
file_pos_write(file, pos);
fput_light(file, fput_needed);
}

return ret;
}

Here, the bulk of the work is done byvfs_read, as described in Chapter 8.

Free download pdf