Implementation of Handler Functions

Let us first take a close look at what's behind C implementation of the actual handler functions. These functions are spread across the kernel because they are embedded in code sections to which they are most closely related in terms of their purpose. For example, all file-related system calls reside in the fs/ kernel subdirectory because they interact directly with the virtual filesystem. Likewise, all memory management calls reside in the files of the mm/ subdirectory.

The handler functions for implementing system calls share several formal features:

□ The name of each function is prefixed with sys_ to uniquely identify the function as a system call — or to be more accurate, as a handler function for a system call. Generally, it is not necessary to distinguish between handler function and system call. In the sections below, I do so only where necessary.

□ All handler functions accept a maximum of five parameters; these are specified in a parameter list as in normal C functions (how parameters are supplied with values differs slightly from the classic approach, as you will see shortly).

□ All system calls are executed in kernel mode. Consequently, the restrictions discussed in Chapter 2 apply, primarily that direct access to user mode memory is not permitted. Recall that copy_from_user, copy_to_user, or other functions from this family must ensure that the desired memory region is available to the kernel before doing the actual read/write operation.

Once the kernel has transferred control to the handler routine, it returns to completely neutral code that is not dependent on a particular CPU or architecture. However, there are exceptions — for various reasons, 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 simple return followed 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.





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

The above approach greatly simplifies the work of programmers because handler functions are implemented 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, the getuid system call to return the UID of the current process is implemented as follows:

Continue reading here: Kerneltimerc

Was this article helpful?

0 0