590 lines
No EOL
41 KiB
HTML
590 lines
No EOL
41 KiB
HTML
|
||
<!DOCTYPE html>
|
||
|
||
|
||
|
||
|
||
<html lang="en">
|
||
<head>
|
||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||
|
||
<title>2.4. System Call Interface — Computer Systems Fundamentals</title>
|
||
|
||
<link rel="stylesheet" href="_static/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous" />
|
||
<link rel="stylesheet" href="_static/css/pygments.css" type="text/css" />
|
||
<link rel="stylesheet" href="_static/css/normalize.css" type="text/css" />
|
||
<link rel="stylesheet" href="../../../JSAV/css/JSAV.css" type="text/css" />
|
||
<link rel="stylesheet" href="../../../lib/odsaMOD-min.css" type="text/css" />
|
||
<link rel="stylesheet" href="_static/css/jquery-1.11.4-smoothness-ui.css" type="text/css" />
|
||
<link rel="stylesheet" href="../../../lib/odsaStyle-min.css" type="text/css" />
|
||
<link rel="stylesheet" href="_static/css/csf.css" type="text/css" />
|
||
|
||
<style>
|
||
.underline { text-decoration: underline; }
|
||
</style>
|
||
|
||
<script type="text/javascript">
|
||
var DOCUMENTATION_OPTIONS = {
|
||
URL_ROOT: './',
|
||
VERSION: '0.4.1',
|
||
COLLAPSE_INDEX: false,
|
||
FILE_SUFFIX: '.html',
|
||
HAS_SOURCE: true
|
||
};
|
||
</script>
|
||
|
||
<script type="text/x-mathjax-config">
|
||
MathJax.Hub.Config({
|
||
tex2jax: {
|
||
inlineMath: [['$','$'], ['\\(','\\)']],
|
||
displayMath: [ ['$$','$$'], ["\\[","\\]"] ],
|
||
processEscapes: true
|
||
},
|
||
"HTML-CSS": {
|
||
scale: "80"
|
||
}
|
||
});
|
||
</script>
|
||
<link rel="shortcut icon" href="_static/favicon.ico"/>
|
||
<link rel="index" title="Index" href="genindex.html" />
|
||
<link rel="search" title="Search" href="search.html" />
|
||
<link rel="index" title="Computer Systems Fundamentals" href="index.html" />
|
||
<link rel="next" title="5. Process Life Cycle" href="ProcessCycle.html" />
|
||
<link rel="prev" title="3. Kernel Mechanics" href="KernelMechanics.html" />
|
||
|
||
</head><body>
|
||
|
||
<nav class="navbar navbar-expand-md navbar-dark navbar-custom fixed-top">
|
||
|
||
<a class="navbar-brand py-0" href="index.html"><img src="_static/CSF-Logo-Square-Text.png" alt="OpenCSF Logo" height="40em" class="py-1 px-2 mb-0 align-center rounded-lg bg-white" /></a>
|
||
<!-- Show a navbar toggler on mobile -->
|
||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#defaultNavbars" aria-controls="defaultNavbars" aria-expanded="false" aria-label="Toggle navigation">
|
||
<span class="navbar-toggler-icon"></span>
|
||
</button>
|
||
<div class="collapse navbar-collapse" id="defaultNavbars">
|
||
<ul class="navbar-nav mr-auto">
|
||
<li class="nav-item dropdown">
|
||
<a class="nav-link dropdown-toggle jmu-gold rounded" href="Syscall.html#" id="navbarDropdownChapters" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Contents</a>
|
||
<div class="dropdown-menu scrollable-menu" role="menu" aria-labelledby="navbarDropdownChapters">
|
||
<a class="dropdown-item" tabindex="-1" href="Syscall.html#"><b>Chapter 1</b></a>
|
||
<a class="dropdown-item" href="IntroConcSysOverview.html"> 1.1. Introduction to Concurrent Systems</a>
|
||
<a class="dropdown-item" href="SysAndModels.html"> 1.2. Systems and Models</a>
|
||
<a class="dropdown-item" href="Themes.html"> 1.3. Themes and Guiding Principles</a>
|
||
<a class="dropdown-item" href="Architectures.html"> 1.4. System Architectures</a>
|
||
<a class="dropdown-item" href="StateModels.html"> 1.5. State Models in UML</a>
|
||
<a class="dropdown-item" href="SequenceModels.html"> 1.6. Sequence Models in UML</a>
|
||
<a class="dropdown-item" href="StateModelImplementation.html"> 1.7. Extended Example: State Model Implementation</a>
|
||
<div class="dropdown-divider"></div>
|
||
<a class="dropdown-item disabled"><b>Chapter 2</b></a>
|
||
<a class="dropdown-item" href="ProcessesOverview.html"> 2.1. Processes and OS Basics</a>
|
||
<a class="dropdown-item" href="Multiprogramming.html"> 2.2. Processes and Multiprogramming</a>
|
||
<a class="dropdown-item" href="KernelMechanics.html"> 2.3. Kernel Mechanics</a>
|
||
<a class="dropdown-item" href="Syscall.html"> 2.4. System Call Interface</a>
|
||
<a class="dropdown-item" href="ProcessCycle.html"> 2.5. Process Life Cycle</a>
|
||
<a class="dropdown-item" href="UnixFile.html"> 2.6. The UNIX File Abstraction</a>
|
||
<a class="dropdown-item" href="EventsSignals.html"> 2.7. Events and Signals</a>
|
||
<a class="dropdown-item" href="Extended2Processes.html"> 2.8. Extended Example: Listing Files with Processes</a>
|
||
<div class="dropdown-divider"></div>
|
||
<a class="dropdown-item disabled"><b>Chapter 3</b></a>
|
||
<a class="dropdown-item" href="IPCOverview.html"> 3.1. Concurrency with IPC</a>
|
||
<a class="dropdown-item" href="IPCModels.html"> 3.2. IPC Models</a>
|
||
<a class="dropdown-item" href="Pipes.html"> 3.3. Pipes and FIFOs</a>
|
||
<a class="dropdown-item" href="MMap.html"> 3.4. Shared Memory With Memory-mapped Files</a>
|
||
<a class="dropdown-item" href="POSIXvSysV.html"> 3.5. POSIX vs. System V IPC</a>
|
||
<a class="dropdown-item" href="MQueues.html"> 3.6. Message Passing With Message Queues</a>
|
||
<a class="dropdown-item" href="ShMem.html"> 3.7. Shared Memory</a>
|
||
<a class="dropdown-item" href="IPCSems.html"> 3.8. Semaphores</a>
|
||
<a class="dropdown-item" href="Extended3Bash.html"> 3.9. Extended Example: Bash-lite: A Simple Command-line Shell</a>
|
||
<div class="dropdown-divider"></div>
|
||
<a class="dropdown-item disabled"><b>Chapter 4</b></a>
|
||
<a class="dropdown-item" href="SocketsOverview.html"> 4.1. Networked Concurrency</a>
|
||
<a class="dropdown-item" href="FiveLayer.html"> 4.2. The TCP/IP Internet Model</a>
|
||
<a class="dropdown-item" href="NetApps.html"> 4.3. Network Applications and Protocols</a>
|
||
<a class="dropdown-item" href="Sockets.html"> 4.4. The Socket Interface</a>
|
||
<a class="dropdown-item" href="TCPSockets.html"> 4.5. TCP Socket Programming: HTTP</a>
|
||
<a class="dropdown-item" href="UDPSockets.html"> 4.6. UDP Socket Programming: DNS</a>
|
||
<a class="dropdown-item" href="AppBroadcast.html"> 4.7. Application-Layer Broadcasting: DHCP</a>
|
||
<a class="dropdown-item" href="Extended4CGI.html"> 4.8. Extended Example: CGI Web Server</a>
|
||
<div class="dropdown-divider"></div>
|
||
<a class="dropdown-item disabled"><b>Chapter 5</b></a>
|
||
<a class="dropdown-item" href="InternetOverview.html"> 5.1. The Internet and Connectivity</a>
|
||
<a class="dropdown-item" href="AppLayer.html"> 5.2. Application Layer: Overlay Networks</a>
|
||
<a class="dropdown-item" href="TransLayer.html"> 5.3. Transport Layer</a>
|
||
<a class="dropdown-item" href="NetSec.html"> 5.4. Network Security Fundamentals</a>
|
||
<a class="dropdown-item" href="NetLayer.html"> 5.5. Network Layer: IP</a>
|
||
<a class="dropdown-item" href="LinkLayer.html"> 5.6. Link Layer</a>
|
||
<a class="dropdown-item" href="Wireless.html"> 5.7. Wireless Connectivity: Wi-Fi, Bluetooth, and Zigbee</a>
|
||
<a class="dropdown-item" href="Extended5DNS.html"> 5.8. Extended Example: DNS client</a>
|
||
<div class="dropdown-divider"></div>
|
||
<a class="dropdown-item disabled"><b>Chapter 6</b></a>
|
||
<a class="dropdown-item" href="ThreadsOverview.html"> 6.1. Concurrency with Multithreading</a>
|
||
<a class="dropdown-item" href="ProcVThreads.html"> 6.2. Processes vs. Threads</a>
|
||
<a class="dropdown-item" href="RaceConditions.html"> 6.3. Race Conditions and Critical Sections</a>
|
||
<a class="dropdown-item" href="POSIXThreads.html"> 6.4. POSIX Thread Library</a>
|
||
<a class="dropdown-item" href="ThreadArgs.html"> 6.5. Thread Arguments and Return Values</a>
|
||
<a class="dropdown-item" href="ImplicitThreads.html"> 6.6. Implicit Threading and Language-based Threads</a>
|
||
<a class="dropdown-item" href="Extended6Input.html"> 6.7. Extended Example: Keyboard Input Listener</a>
|
||
<a class="dropdown-item" href="Extended6Primes.html"> 6.8. Extended Example: Concurrent Prime Number Search</a>
|
||
<div class="dropdown-divider"></div>
|
||
<a class="dropdown-item disabled"><b>Chapter 7</b></a>
|
||
<a class="dropdown-item" href="SynchOverview.html"> 7.1. Synchronization Primitives</a>
|
||
<a class="dropdown-item" href="CritSect.html"> 7.2. Critical Sections and Peterson's Solution</a>
|
||
<a class="dropdown-item" href="Locks.html"> 7.3. Locks</a>
|
||
<a class="dropdown-item" href="Semaphores.html"> 7.4. Semaphores</a>
|
||
<a class="dropdown-item" href="Barriers.html"> 7.5. Barriers</a>
|
||
<a class="dropdown-item" href="Condvars.html"> 7.6. Condition Variables</a>
|
||
<a class="dropdown-item" href="Deadlock.html"> 7.7. Deadlock</a>
|
||
<a class="dropdown-item" href="Extended7Events.html"> 7.8. Extended Example: Event Log File</a>
|
||
<div class="dropdown-divider"></div>
|
||
<a class="dropdown-item disabled"><b>Chapter 8</b></a>
|
||
<a class="dropdown-item" href="SynchProblemsOverview.html"> 8.1. Synchronization Patterns and Problems</a>
|
||
<a class="dropdown-item" href="SynchDesign.html"> 8.2. Basic Synchronization Design Patterns</a>
|
||
<a class="dropdown-item" href="ProdCons.html"> 8.3. Producer-Consumer Problem</a>
|
||
<a class="dropdown-item" href="ReadWrite.html"> 8.4. Readers-Writers Problem</a>
|
||
<a class="dropdown-item" href="DiningPhil.html"> 8.5. Dining Philosophers Problem and Deadlock</a>
|
||
<a class="dropdown-item" href="CigSmokers.html"> 8.6. Cigarette Smokers Problem and the Limits of Semaphores and Locks</a>
|
||
<a class="dropdown-item" href="Extended8ModExp.html"> 8.7. Extended Example: Parallel Modular Exponentiation</a>
|
||
<div class="dropdown-divider"></div>
|
||
<a class="dropdown-item disabled"><b>Chapter 9</b></a>
|
||
<a class="dropdown-item" href="ParallelDistributedOverview.html"> 9.1. Parallel and Distributed Systems</a>
|
||
<a class="dropdown-item" href="ParVConc.html"> 9.2. Parallelism vs. Concurrency</a>
|
||
<a class="dropdown-item" href="ParallelDesign.html"> 9.3. Parallel Design Patterns</a>
|
||
<a class="dropdown-item" href="Scaling.html"> 9.4. Limits of Parallelism and Scaling</a>
|
||
<a class="dropdown-item" href="DistTiming.html"> 9.5. Timing in Distributed Environments</a>
|
||
<a class="dropdown-item" href="DistDataStorage.html"> 9.6. Reliable Data Storage and Location</a>
|
||
<a class="dropdown-item" href="DistConsensus.html"> 9.7. Consensus in Distributed Systems</a>
|
||
<a class="dropdown-item" href="Extended9Blockchain.html"> 9.8. Extended Example: Blockchain Proof-of-Work</a>
|
||
<div class="dropdown-divider"></div>
|
||
<a class="dropdown-item disabled"><b>Appendix A</b></a>
|
||
<a class="dropdown-item" href="CLangOverview.html"> A.1. C Language Reintroduction</a>
|
||
<a class="dropdown-item" href="Debugging.html"> A.2. Documentation and Debugging</a>
|
||
<a class="dropdown-item" href="BasicTypes.html"> A.3. Basic Types and Pointers</a>
|
||
<a class="dropdown-item" href="Arrays.html"> A.4. Arrays, Structs, Enums, and Type Definitions</a>
|
||
<a class="dropdown-item" href="Functions.html"> A.5. Functions and Scope</a>
|
||
<a class="dropdown-item" href="Pointers.html"> A.6. Pointers and Dynamic Allocation</a>
|
||
<a class="dropdown-item" href="Strings.html"> A.7. Strings</a>
|
||
<a class="dropdown-item" href="FunctionPointers.html"> A.8. Function Pointers</a>
|
||
<a class="dropdown-item" href="Files.html"> A.9. Files</a>
|
||
</div>
|
||
</li>
|
||
|
||
|
||
|
||
</ul>
|
||
</div>
|
||
|
||
<ul class="navbar-nav flex-row ml-md-auto d-none d-md-flex">
|
||
<li class="nav-item"><a class="nav-link jmu-gold" href="https://w3.cs.jmu.edu/kirkpams/OpenCSF/Books/csf/source/Syscall.rst"
|
||
target="_blank" rel="nofollow">Show Source</a></li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
|
||
<div class="container center">
|
||
«  <a id="prevmod" href="KernelMechanics.html">2.3. Kernel Mechanics</a>
|
||
  ::  
|
||
<a class="uplink" href="index.html">Contents</a>
|
||
  ::  
|
||
<a id="nextmod" href="ProcessCycle.html">2.5. Process Life Cycle</a>  »
|
||
|
||
</div>
|
||
<br />
|
||
|
||
|
||
|
||
<script type="text/javascript" src="_static/js/jquery-2.1.4.min.js"></script>
|
||
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
|
||
<script type="text/javascript" src="_static/js/jquery-1.11.4-ui.min.js"></script>
|
||
<script type="text/javascript" src="_static/js/forge-0.7.0.min.js"></script>
|
||
<script type="text/javascript" src="../../../JSAV/lib/jquery.transit.js"></script>
|
||
<script type="text/javascript" src="../../../JSAV/lib/raphael.js"></script>
|
||
<script type="text/javascript" src="../../../JSAV/build/JSAV-min.js"></script>
|
||
<script type="text/javascript" src="_static/js/config.js"></script>
|
||
<script type="text/javascript" src="../../../lib/odsaUtils-min.js"></script>
|
||
<script type="text/javascript" src="../../../lib/odsaMOD-min.js"></script>
|
||
<script type="text/javascript" src="_static/js/d3-4.13.0.min.js"></script>
|
||
<script type="text/javascript" src="_static/js/d3-selection-multi.v1.min.js"></script>
|
||
<script type="text/javascript" src="../../../lib/dataStructures.js"></script>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<div class="container">
|
||
|
||
<script>ODSA.SETTINGS.DISP_MOD_COMP = true;ODSA.SETTINGS.MODULE_NAME = "Syscall";ODSA.SETTINGS.MODULE_LONG_NAME = "System Call Interface";ODSA.SETTINGS.MODULE_CHAPTER = "Processes and OS Basics"; ODSA.SETTINGS.BUILD_DATE = "2021-06-14 17:15:25"; ODSA.SETTINGS.BUILD_CMAP = false;JSAV_OPTIONS['lang']='en';JSAV_EXERCISE_OPTIONS['code']='java';</script><div class="section" id="system-call-interface">
|
||
<h1>2.4. System Call Interface<a class="headerlink" href="Syscall.html#system-call-interface" title="Permalink to this headline">¶</a></h1>
|
||
<p>User-mode programs can execute standard CPU instructions that are focused on performing a
|
||
calculation or implementing a logical control flow. However, user-mode programs have no direct
|
||
access to any shared computing resource outside the CPU. For instance, user-mode software cannot
|
||
read data from a hard drive, send data across a network interface, or even display information to
|
||
the monitor screen. Instead, the user-mode program must execute a system call to request the kernel
|
||
perform this action on its behalf.</p>
|
||
<div class="section" id="system-calls-vs-function-calls">
|
||
<h2>2.4.1. System Calls vs. Function Calls<a class="headerlink" href="Syscall.html#system-calls-vs-function-calls" title="Permalink to this headline">¶</a></h2>
|
||
<p>At the level of assembly language, a system call involves executing a trap instruction. In modern
|
||
x86 code, the trap instruction is <code class="docutils literal notranslate"><span class="pre">syscall</span></code> <a class="footnote-reference" href="Syscall.html#f10" id="id1">[1]</a> , which acts in a manner analogous to call.
|
||
Instead of jumping to a function within the same program, though, <code class="docutils literal notranslate"><span class="pre">syscall</span></code> triggers a mode switch
|
||
and jumps to a routine in the kernel portion of memory. The kernel validates the system call
|
||
parameters and checks the process’s access permissions. For instance, if the system call is a
|
||
request to write to a file, the kernel will determine whether the user running the program is
|
||
allowed to perform this action. Once the kernel has finished performing the system call, it uses the
|
||
<code class="docutils literal notranslate"><span class="pre">sysret</span></code> instruction, which performs a role similar to the standard <code class="docutils literal notranslate"><span class="pre">ret</span></code> instruction. The
|
||
difference is that sysret also changes the privilege level, returning the system to user mode.</p>
|
||
<p>From a higher level perspective, system calls are often written to look like standard C functions.
|
||
For instance, it is common to find references to the <code class="docutils literal notranslate"><span class="pre">write()</span></code> system call. This practice is
|
||
simply a form of short-hand notation. In most cases, there is a C function that acts as a wrapper
|
||
for the system call. That is, there is a C function called <code class="docutils literal notranslate"><span class="pre">write()</span></code> in the C standard library;
|
||
this function will perform a few initial steps before triggering the <code class="docutils literal notranslate"><span class="pre">syscall</span></code> trap instruction.
|
||
To be clear, there is a distinction between the <code class="docutils literal notranslate"><span class="pre">write()</span></code> C function and the system call, but this
|
||
distinction is often blurred in practice.</p>
|
||
</div>
|
||
<div class="section" id="linux-system-calls">
|
||
<h2>2.4.2. Linux System Calls<a class="headerlink" href="Syscall.html#linux-system-calls" title="Permalink to this headline">¶</a></h2>
|
||
<p>The Linux source code repository contains the full list of Linux system calls. <a class="footnote-reference" href="Syscall.html#f11" id="id2">[2]</a> This table
|
||
identifies the mapping between the system call number (which actually specifies the system call),
|
||
the name that is commonly used, and the entry point routine within the Linux kernel itself. For
|
||
instance, system call 0 is the <code class="docutils literal notranslate"><span class="pre">read()</span></code> system call. When a user-mode program executes the
|
||
<code class="docutils literal notranslate"><span class="pre">read()</span></code> system call, the system will trigger a mode switch and jump to the <code class="docutils literal notranslate"><span class="pre">sys_read()</span></code>
|
||
function within the Linux kernel.</p>
|
||
<p>There are a couple of observations that can be made from this table. First, every system call has a
|
||
unique number associated with it. As we will explain next, x86 system call mechanics only use this
|
||
number. The name that associated with each number is just to give meaning to the programmer, just as
|
||
we use function names instead of relying on memorization of hard-coded addresses. Second, the names
|
||
of the entry point functions in Linux are the names of the system calls with <code class="docutils literal notranslate"><span class="pre">sys_</span></code> prepended; for
|
||
instance, the <code class="docutils literal notranslate"><span class="pre">open()</span></code> system call will call the <code class="docutils literal notranslate"><span class="pre">sys_open()</span></code> function in the kernel, and
|
||
<code class="docutils literal notranslate"><span class="pre">mmap()</span></code> will call <code class="docutils literal notranslate"><span class="pre">sys_mmap()</span></code>.</p>
|
||
<p>Lastly, note that the names of the system calls correspond to many common C standard library
|
||
functions. For instance, <code class="docutils literal notranslate"><span class="pre">open()</span></code> and <code class="docutils literal notranslate"><span class="pre">close()</span></code> are the system calls that are used to establish
|
||
connections to files, <code class="docutils literal notranslate"><span class="pre">socket()</span></code> is the system call to create a socket for network communication,
|
||
and <code class="docutils literal notranslate"><span class="pre">exit()</span></code> can be used to terminate the current process. That is, many C functions are simply
|
||
wrappers for system calls.</p>
|
||
<p>In contrast, many C functions are implemented to provide additional functionality on top of system
|
||
calls. In the case of <code class="docutils literal notranslate"><span class="pre">printf()</span></code>, the code will eventually trigger the <code class="docutils literal notranslate"><span class="pre">write()</span></code> system call.
|
||
The primary difference is that <code class="docutils literal notranslate"><span class="pre">write()</span></code> requires low-level details of how the system is being
|
||
used that <code class="docutils literal notranslate"><span class="pre">printf()</span></code> abstracts away. In addition, calling <code class="docutils literal notranslate"><span class="pre">write()</span></code> requires exact knowledge of
|
||
the length of the message to be printed, whereas <code class="docutils literal notranslate"><span class="pre">printf()</span></code> does not. In summary, many C standard
|
||
library functions provide a thin wrapper for invoking system calls, while other functions do not.</p>
|
||
<p><a class="reference external" href="Syscall.html#tbl2-1">Table 2.1</a> lists a small sample of the more than 300 system calls available on 64-bit Linux systems.
|
||
The full list of system calls can be found in the <code class="docutils literal notranslate"><span class="pre">syscalls(2)</span></code> man or in <code class="docutils literal notranslate"><span class="pre"><asm/unistd_64.h></span></code>,
|
||
which is included (through a nested sequence of headers) by <code class="docutils literal notranslate"><span class="pre"><sys/syscall.h></span></code>. <a class="footnote-reference" href="Syscall.html#f12" id="id3">[3]</a> Each system
|
||
call is documented in a section 2 man page <a class="footnote-reference" href="Syscall.html#f13" id="id4">[4]</a> (e.g., <code class="docutils literal notranslate"><span class="pre">man</span> <span class="pre">2</span> <span class="pre">read</span></code>).</p>
|
||
<center>
|
||
<div class="row">
|
||
<div class="col-12">
|
||
<table class="table table-bordered">
|
||
<thead class="jmu-dark-purple-bg text-light">
|
||
<tr>
|
||
<th class="py-0 center">Syscall</th>
|
||
<th class="py-0 center">Number</th>
|
||
<th class="py-0 center">Purpose</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td class="py-0"><code>read</code></td>
|
||
<td class="py-0">0</td>
|
||
<td class="py-0">Read from a file descriptor</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0"><code>write</code></td>
|
||
<td class="py-0">1</td>
|
||
<td class="py-0">Write to a file descriptor</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0"><code>nanosleep</code></td>
|
||
<td class="py-0">35</td>
|
||
<td class="py-0">High-resolution sleep (units in seconds and nanoseconds)</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0"><code>exit</code></td>
|
||
<td class="py-0">60</td>
|
||
<td class="py-0">Terminate the current process</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0"><code>kill</code></td>
|
||
<td class="py-0">62</td>
|
||
<td class="py-0">Send a signal to a process</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0"><code>uname</code></td>
|
||
<td class="py-0">63</td>
|
||
<td class="py-0">Get information (name, release, etc.) about the current kernel</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0"><code>gettimeofday</code></td>
|
||
<td class="py-0">96</td>
|
||
<td class="py-0">Get the system time (in seconds since 12:00 AM Jan. 1, 1970)</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0"><code>sysinfo</code></td>
|
||
<td class="py-0">99</td>
|
||
<td class="py-0">Get information about memory usage and CPU load average</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0"><code>ptrace</code></td>
|
||
<td class="py-0">101</td>
|
||
<td class="py-0">Trace another process's execution</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p>
|
||
Table 2.1: A sample of common Linux system calls
|
||
</p>
|
||
</center></div>
|
||
<div class="section" id="calling-system-calls-in-assembly">
|
||
<h2>2.4.3. Calling System Calls in Assembly<a class="headerlink" href="Syscall.html#calling-system-calls-in-assembly" title="Permalink to this headline">¶</a></h2>
|
||
<p>In assembly language, a system call looks almost exactly like a function call. Arguments are passed
|
||
to the system call using the general purpose registers and the stack as needed. The main difference
|
||
is that the system call number is stored into the <code class="docutils literal notranslate"><span class="pre">%rax</span></code> register. As an example, we can write a
|
||
standard “Hello, world” program in assembly language using two system calls.</p>
|
||
<p>In <a class="reference external" href="Syscall.html#cl2-3">Code Listing 2.3</a>, the four mov instructions (lines 9 – 12) set up the arguments for the
|
||
<code class="docutils literal notranslate"><span class="pre">write()</span></code> system call, which expects three arguments: the file handle to write to, the address of
|
||
the message to write, and the length of the message in bytes. As with a normal function, these are
|
||
passed in the <code class="docutils literal notranslate"><span class="pre">%rdi</span></code>, <code class="docutils literal notranslate"><span class="pre">%rsi</span></code>, and <code class="docutils literal notranslate"><span class="pre">%rdx</span></code> registers. In a normal function call, the <code class="docutils literal notranslate"><span class="pre">call</span></code>
|
||
instruction would specify the function to execute. However, <code class="docutils literal notranslate"><span class="pre">syscall</span></code> does not encode this
|
||
information. Instead, on line 5, we moved the constant 1 into <code class="docutils literal notranslate"><span class="pre">%rax</span></code>, as this is the number for
|
||
the <code class="docutils literal notranslate"><span class="pre">write()</span></code> system call. Similarly, lines 16 and 17 indicate that the <code class="docutils literal notranslate"><span class="pre">exit()</span></code> system call
|
||
should be invoked with the value 0 as a parameter.</p>
|
||
<div class="highlight-asm border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl2-3"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0"> 1
|
||
2
|
||
3
|
||
4
|
||
5
|
||
6
|
||
7
|
||
8
|
||
9
|
||
10
|
||
11
|
||
12
|
||
13
|
||
14
|
||
15
|
||
16
|
||
17
|
||
18
|
||
19
|
||
20
|
||
21
|
||
22</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="c"># Code Listing 2.3:</span>
|
||
<span class="c"># An assembly-language “hello world” program with system calls</span>
|
||
|
||
<span class="na">.global</span> <span class="no">_start</span>
|
||
|
||
<span class="no">.text</span>
|
||
<span class="nl">_start:</span>
|
||
<span class="c"># write(1, message, 13)</span>
|
||
<span class="nf">mov</span> <span class="no">$1</span><span class="p">,</span> <span class="nv">%rax</span> <span class="c"># system call 1 is write</span>
|
||
<span class="no">mov</span> <span class="no">$1</span><span class="p">,</span> <span class="nv">%rdi</span> <span class="c"># file handle 1 is stdout</span>
|
||
<span class="no">mov</span> <span class="no">$message</span><span class="p">,</span> <span class="nv">%rsi</span> <span class="c"># address of string to output</span>
|
||
<span class="no">mov</span> <span class="no">$13</span><span class="p">,</span> <span class="nv">%rdx</span> <span class="c"># number of bytes</span>
|
||
<span class="no">syscall</span> <span class="c"># invoke OS to write to stdout</span>
|
||
|
||
<span class="c"># exit(0)</span>
|
||
<span class="nf">mov</span> <span class="no">$60</span><span class="p">,</span> <span class="nv">%rax</span> <span class="c"># system call 60 is exit</span>
|
||
<span class="no">xor</span> <span class="nv">%rdi</span><span class="p">,</span> <span class="nv">%rdi</span> <span class="c"># we want return code 0</span>
|
||
<span class="no">syscall</span> <span class="c"># invoke OS to exit</span>
|
||
|
||
<span class="na">.data</span>
|
||
<span class="nl">message:</span>
|
||
<span class="na">.ascii</span> <span class="s">"Hello, world\n"</span>
|
||
</pre></div>
|
||
</td></tr></table></div>
|
||
<p>Many system calls have return values that can be used to determine if an error occurred. As with
|
||
standard functions, the kernel puts return values in the <code class="docutils literal notranslate"><span class="pre">%rax</span></code> register. Negative values in the
|
||
range of -4095 to -1 indicate an error.</p>
|
||
</div>
|
||
<div class="section" id="calling-system-calls-with-syscall">
|
||
<h2>2.4.4. Calling System Calls with syscall()<a class="headerlink" href="Syscall.html#calling-system-calls-with-syscall" title="Permalink to this headline">¶</a></h2>
|
||
<p>Another method for invoking Linux system calls directly is to use <code class="docutils literal notranslate"><span class="pre">syscall()</span></code>. For instance, the
|
||
program in <a class="reference external" href="Syscall.html#cl2-4">Code Listing 2.4</a> shows the C equivalent of the assembly language code shown in Code
|
||
Listing 2.3. As before, we can bypass the C standard library functions for <code class="docutils literal notranslate"><span class="pre">write()</span></code> and
|
||
<code class="docutils literal notranslate"><span class="pre">exit()</span></code> by invoking the system call directly. Specifcally, lines 12 and 13 make two system calls,
|
||
although they look like standard function calls. The C compiler will translate these into the
|
||
sequence of instructions in lines 9 – 13 and 16 – 18 from <a class="reference external" href="Syscall.html#cl2-3">Code Listing 2.3</a>.</p>
|
||
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl2-4"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0"> 1
|
||
2
|
||
3
|
||
4
|
||
5
|
||
6
|
||
7
|
||
8
|
||
9
|
||
10
|
||
11
|
||
12
|
||
13
|
||
14
|
||
15
|
||
16
|
||
17
|
||
18</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing 2.4:</span>
|
||
<span class="cm"> Using syscall() in C to invoke Linux system calls for writing and exiting</span>
|
||
<span class="cm"> */</span>
|
||
|
||
<span class="cp">#include</span> <span class="cpf"><unistd.h></span><span class="cp"></span>
|
||
|
||
<span class="kt">char</span> <span class="o">*</span><span class="n">message</span> <span class="o">=</span> <span class="s">"Hello, world</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span>
|
||
|
||
<span class="kt">int</span>
|
||
<span class="nf">main</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span>
|
||
<span class="p">{</span>
|
||
<span class="n">syscall</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="n">message</span><span class="p">,</span> <span class="mi">13</span><span class="p">);</span>
|
||
<span class="n">syscall</span> <span class="p">(</span><span class="mi">60</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
|
||
|
||
<span class="cm">/* should never reach here */</span>
|
||
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
|
||
<span class="p">}</span>
|
||
|
||
</pre></div>
|
||
</td></tr></table></div>
|
||
<p>One aspect to note about the implementation of <code class="docutils literal notranslate"><span class="pre">syscall()</span></code> is that its parameters get passed in
|
||
the wrong registers. Specifically, the compiler mostly treats <code class="docutils literal notranslate"><span class="pre">syscall()</span></code> as a regular function
|
||
call, but it passes the first parameter in <code class="docutils literal notranslate"><span class="pre">%rdi</span></code> instead of the standard <code class="docutils literal notranslate"><span class="pre">%rax</span></code>, because the
|
||
kernel expects the system call number to be in <code class="docutils literal notranslate"><span class="pre">%rdi</span></code>. <a class="reference external" href="Syscall.html#cl2-5">Code Listing 2.5</a> shows how Linux implements
|
||
<code class="docutils literal notranslate"><span class="pre">syscall()</span></code>, shifting the register values as needed (lines 9 – 13) and invoking the <code class="docutils literal notranslate"><span class="pre">syscall</span></code> instruction.</p>
|
||
<div class="highlight-asm border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl2-5"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0"> 1
|
||
2
|
||
3
|
||
4
|
||
5
|
||
6
|
||
7
|
||
8
|
||
9
|
||
10
|
||
11
|
||
12
|
||
13
|
||
14
|
||
15
|
||
16
|
||
17
|
||
18
|
||
19
|
||
20
|
||
21
|
||
22</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="c"># Code Listing 2.5:</span>
|
||
<span class="c"># The Linux implementation of the C syscall() function</span>
|
||
|
||
<span class="c"># From sysdeps/unix/sysv/linux/x86_64/syscall.S</span>
|
||
|
||
<span class="na">.text</span>
|
||
<span class="nf">ENTRY</span> <span class="p">(</span><span class="no">syscall</span><span class="p">)</span>
|
||
<span class="nf">movq</span> <span class="nv">%rdi</span><span class="p">,</span> <span class="nv">%rax</span> <span class="c"># Syscall number -> rax.</span>
|
||
<span class="no">movq</span> <span class="nv">%rsi</span><span class="p">,</span> <span class="nv">%rdi</span> <span class="c"># shift arg1 - arg5.</span>
|
||
<span class="no">movq</span> <span class="nv">%rdx</span><span class="p">,</span> <span class="nv">%rsi</span>
|
||
<span class="nf">movq</span> <span class="nv">%rcx</span><span class="p">,</span> <span class="nv">%rdx</span>
|
||
<span class="nf">movq</span> <span class="nv">%r8</span><span class="p">,</span> <span class="nv">%r10</span>
|
||
<span class="nf">movq</span> <span class="nv">%r9</span><span class="p">,</span> <span class="nv">%r8</span>
|
||
<span class="nf">movq</span> <span class="mi">8</span><span class="p">(</span><span class="nv">%rsp</span><span class="p">),</span><span class="nv">%r9</span> <span class="c"># arg6 is on the stack.</span>
|
||
<span class="no">syscall</span> <span class="c"># Do the system call.</span>
|
||
<span class="no">cmpq</span> <span class="no">$-4095</span><span class="p">,</span> <span class="nv">%rax</span> <span class="c"># Check %rax for error.</span>
|
||
<span class="no">jae</span> <span class="no">SYSCALL_ERROR_LABEL</span> <span class="c"># Jump to error handler if error.</span>
|
||
|
||
<span class="nf">L</span><span class="p">(</span><span class="no">pseudo_end</span><span class="p">):</span>
|
||
<span class="nf">ret</span> <span class="c"># Return to caller.</span>
|
||
|
||
<span class="nf">PSEUDO_END</span> <span class="p">(</span><span class="no">syscall</span><span class="p">)</span>
|
||
</pre></div>
|
||
</td></tr></table></div>
|
||
<table class="docutils footnote" frame="void" id="f10" rules="none">
|
||
<colgroup><col class="label" /><col /></colgroup>
|
||
<tbody valign="top">
|
||
<tr><td class="label"><a class="fn-backref" href="Syscall.html#id1">[1]</a></td><td>The <code class="docutils literal notranslate"><span class="pre">syscall</span></code> instruction is the primary trap instruction in 64-bit x86 systems. Earlier
|
||
x86 programs performed system calls by triggering an interrupt with the <code class="docutils literal notranslate"><span class="pre">int</span> <span class="pre">$0x80</span></code> instruction;
|
||
the kernel would use <code class="docutils literal notranslate"><span class="pre">iret</span></code> to return from the interrupt. For performance reasons, this approach
|
||
was replaced with the <code class="docutils literal notranslate"><span class="pre">sysenter</span></code> and <code class="docutils literal notranslate"><span class="pre">sysexit</span></code> instructions on 32-bit systems. <code class="docutils literal notranslate"><span class="pre">syscall</span></code> and
|
||
<code class="docutils literal notranslate"><span class="pre">sysret</span></code> are the 64-bit equivalent of these faster system call instructions.</td></tr>
|
||
</tbody>
|
||
</table>
|
||
<table class="docutils footnote" frame="void" id="f11" rules="none">
|
||
<colgroup><col class="label" /><col /></colgroup>
|
||
<tbody valign="top">
|
||
<tr><td class="label"><a class="fn-backref" href="Syscall.html#id2">[2]</a></td><td>See <a class="reference external" href="https://github.com/torvalds/linux/blob/v3.13/arch/x86/syscalls/syscall_64.tbl">https://github.com/torvalds/linux/blob/v3.13/arch/x86/syscalls/syscall_64.tbl</a> for example.</td></tr>
|
||
</tbody>
|
||
</table>
|
||
<table class="docutils footnote" frame="void" id="f12" rules="none">
|
||
<colgroup><col class="label" /><col /></colgroup>
|
||
<tbody valign="top">
|
||
<tr><td class="label"><a class="fn-backref" href="Syscall.html#id3">[3]</a></td><td>To prevent naming collisions, the names of the system calls are more complicated than
|
||
shown in the table. Specifically, the <code class="docutils literal notranslate"><span class="pre">Read()</span></code> system call is listed in this table as <code class="docutils literal notranslate"><span class="pre">__NR_read</span></code>.</td></tr>
|
||
</tbody>
|
||
</table>
|
||
<table class="docutils footnote" frame="void" id="f13" rules="none">
|
||
<colgroup><col class="label" /><col /></colgroup>
|
||
<tbody valign="top">
|
||
<tr><td class="label"><a class="fn-backref" href="Syscall.html#id4">[4]</a></td><td>For readers new to man pages, documentation on this system can be found by typing <code class="docutils literal notranslate"><span class="pre">man</span>
|
||
<span class="pre">man</span></code> on the command line. In brief, on Linux and UNIX systems, all C libraries are documented
|
||
through this manual. The manual is divided into several sections, with section 2 used for system
|
||
calls and section 3 used for the C standard library. The section of the manual for a function is
|
||
noted in parentheses after the name. For instance, <code class="docutils literal notranslate"><span class="pre">exit(2)</span></code> documents on the exit system call,
|
||
whereas <code class="docutils literal notranslate"><span class="pre">exit(3)</span></code> documents the standard C library <code class="docutils literal notranslate"><span class="pre">exit()</span></code> function. (Note there is a difference!)</td></tr>
|
||
</tbody>
|
||
</table>
|
||
<div
|
||
id="KernelSyscallSumm"
|
||
class="embedContainer"
|
||
data-exer-name="KernelSyscallSumm"
|
||
data-long-name="System call questions"
|
||
data-short-name="KernelSyscallSumm"
|
||
data-frame-src="../../../Exercises/Processes/KernelSyscallSumm.html?selfLoggingEnabled=false&localMode=true&module=Syscall&JXOP-debug=true&JOP-lang=en&JXOP-code=java"
|
||
data-frame-width="950"
|
||
data-frame-height="550"
|
||
data-external="false"
|
||
data-points="1.0"
|
||
data-required="True"
|
||
data-showhide="show"
|
||
data-threshold="2"
|
||
data-type="ka"
|
||
data-exer-id="">
|
||
|
||
<div class="center">
|
||
<div id="KernelSyscallSumm_iframe"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
</div>
|
||
|
||
|
||
|
||
<div class="container">
|
||
|
||
<div class="mt-4 container center">
|
||
«  <a id="prevmod1" href="KernelMechanics.html">2.3. Kernel Mechanics</a>
|
||
  ::  
|
||
<a class="uplink" href="index.html">Contents</a>
|
||
  ::  
|
||
<a id="nextmod1" href="ProcessCycle.html">2.5. Process Life Cycle</a>  »
|
||
</div>
|
||
|
||
|
||
</div>
|
||
|
||
<br />
|
||
|
||
<div class="row jmu-dark-purple-bg">
|
||
<div class="col-md-12">
|
||
<center>
|
||
<a id="contact_us" class="btn button-link-no-blue jmu-gold" rel="nofollow" href="mailto:webmaster@opencsf.org" role="button">Contact Us</a>
|
||
<a id="license" class="btn button-link-no-blue jmu-gold" rel="nofollow" href="https://w3.cs.jmu.edu/kirkpams/OpenCSF/lib/license.html" target="_blank">License</a>
|
||
</center>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<script src="_static/js/popper.js-1.14.7-min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
|
||
<script src="_static/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
|
||
</body>
|
||
</html> |