Page 18 - DCAP103_Principle of operating system
P. 18
Unit 1: Operating System
it is no longer pointing to A open, so it won’t restore it to sys_open before it is removed from Notes
memory. Unfortunately, B_open will still try to call A open which is no longer there, so that
even without removing B the system would crash.
There are two ways to prevent this problem. The first is to restore the call to the original value,
sys_open. Unfortunately, sys_open is not part of the kernel system table in /proc/ksyms, so we
can’t access it. The other solution is to use the reference count to prevent root from rmmod’ing
the module once it is loaded. This is good for production modules, but bad for an educational
sample which is why I didn’t do it here.
1.5.1 The Library as an Intermediary
Generally, systems provide a library that sits between normal programs and the operating system,
usually an implementation of the C library (libc), such as glibc. This library exists between the
OS and the application, and increases portability.
On exokernel based systems, the library is especially important as an intermediary. On exokernels,
libraries shield user applications from the very low level kernel API, and provide abstractions
and resource management.
1.5.2 Examples and Tools
On Unix, Unix-like and other POSIX-compatible Operating Systems, popular system calls are
open, read, write, close, wait, exec, fork, exit, and kill. Many of today’s operating systems have
hundreds of system calls. For example, Linux has 319 different system calls. Similarly, FreeBSD
has almost 330.
Tools such as strace and truss allow a process to execute from start and report all system calls
the process invokes, or can attach to an already running process and intercept any system call
made by said process if the operation does not violate the permissions of the user. This special
ability of the program is usually also implemented with a system call, e.g. the GNU’s strace is
implemented with ptrace( ).
1.5.3 Typical Implementations
Implementing system calls requires a control transfer which involves some sort of architecture-
specific feature. A typical way to implement this is to use a software interrupt or trap. Interrupts
transfer control to the OS so software simply needs to set up some register with the system call
number they want and execute the software interrupt.
For many RISC processors this is the only feasible implementation, but CISC architectures such
as x86support additional techniques. One example is SYSCALL/SYSENTER, SYSRET/SYSEXIT
(the two mechanisms were independently created by AMD and Intel, respectively, but in essence
do the same thing). These are “fast” control transfer instructions that are designed to quickly
transfer control to the OS for a system call without the overhead of an interrupt. Linux 2.5 began
using this on the x86, where available; formerly it used the INT instruction, where the system
call number was placed in the EAX register before interrupt 0x80 was executed.
An older x86 mechanism is called a call gate and is a way for a program to literally call a
kernel function directly using a safe control transfer mechanism the OS sets up in advance. This
approach has been unpopular, presumably due to the requirement of a far call which uses x86
memory segmentation and the resulting lack of portability it causes, and existence of the faster
instructions mentioned above.
For IA64 architecture, EPC (Enter Privileged Mode) instruction is used. The first eight system
call arguments are passed in registers, and the rest are passed on the stack.
LOVELY PROFESSIONAL UNIVERSITY 11