mirror of
https://github.com/sysprog21/lkmpg.git
synced 2025-04-25 22:14:05 +08:00
deploy: 28018227fcd2b937698408d4080b3aa51aa7fdef
This commit is contained in:
parent
706c09762a
commit
510ed645a9
201
index.html
201
index.html
@ -18,7 +18,7 @@
|
||||
|
||||
<h2 class='titleHead'>The Linux Kernel Module Programming Guide</h2>
|
||||
<div class='author'><span class='ecrm-1200'>Peter Jay Salzman, Michael Burian, Ori Pomerantz, Bob Mottram, Jim Huang</span></div><br />
|
||||
<div class='date'><span class='ecrm-1200'>October 10, 2021</span></div>
|
||||
<div class='date'><span class='ecrm-1200'>October 14, 2021</span></div>
|
||||
|
||||
|
||||
|
||||
@ -3124,12 +3124,7 @@ production use. In order to keep people from doing potential harmful things
|
||||
|
||||
dry run of this example, you will have to patch your current kernel in order to have
|
||||
<code> <span class='ectt-1000'>sys_call_table</span>
|
||||
</code> exported. In the example directory you will find a README and the patch. As you
|
||||
can imagine, such modifications are not to be taken lightly. Do not try this on
|
||||
valuable systems (ie systems that you do not own - or cannot restore easily). You will
|
||||
need to get the complete sourcecode of this guide as a tarball in order to get the
|
||||
patch and the README. Depending on your kernel version, you might even need to
|
||||
hand apply the patch.
|
||||
</code> exported.
|
||||
</p><!-- l. 1 --><p class='indent'>
|
||||
</p>
|
||||
<pre class='fancyvrb' id='fancyvrb51'><a id='x1-40044r1'></a><span class='ecrm-0500'>1</span><span id='textcolor1326'><span class='ectt-0800'>/*</span></span>
|
||||
@ -3361,13 +3356,13 @@ hand apply the patch.
|
||||
<a id='x1-40496r227'></a><span class='ecrm-0500'>227</span><span class='ectt-0800'>module_exit(syscall_end);</span>
|
||||
<a id='x1-40498r228'></a><span class='ecrm-0500'>228</span>
|
||||
<a id='x1-40500r229'></a><span class='ecrm-0500'>229</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor1568'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
||||
<!-- l. 1349 --><p class='noindent'>
|
||||
<!-- l. 1344 --><p class='noindent'>
|
||||
</p>
|
||||
<h3 class='sectionHead' id='blocking-processes-and-threads'><span class='titlemark'>11 </span> <a id='x1-4100011'></a>Blocking Processes and threads</h3>
|
||||
<!-- l. 1351 --><p class='noindent'>
|
||||
<!-- l. 1346 --><p class='noindent'>
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='sleep'><span class='titlemark'>11.1 </span> <a id='x1-4200011.1'></a>Sleep</h4>
|
||||
<!-- l. 1353 --><p class='noindent'>What do you do when somebody asks you for something you can not do right
|
||||
<!-- l. 1348 --><p class='noindent'>What do you do when somebody asks you for something you can not do right
|
||||
away? If you are a human being and you are bothered by a human being, the
|
||||
only thing you can say is: "<span class='ecti-1000'>Not right now, I’m busy. Go away!</span>". But if you
|
||||
are a kernel module and you are bothered by a process, you have another
|
||||
@ -3375,58 +3370,58 @@ possibility. You can put the process to sleep until you can service it. After al
|
||||
processes are being put to sleep by the kernel and woken up all the time (that
|
||||
is the way multiple processes appear to run on the same time on a single
|
||||
CPU).
|
||||
</p><!-- l. 1359 --><p class='indent'> This kernel module is an example of this. The file (called <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>/proc/sleep</span></span></span>) can only
|
||||
</p><!-- l. 1354 --><p class='indent'> This kernel module is an example of this. The file (called <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>/proc/sleep</span></span></span>) can only
|
||||
be opened by a single process at a time. If the file is already open, the kernel module
|
||||
calls <code> <span class='ectt-1000'>wait_event_interruptible</span>
|
||||
</code>. The easiest way to keep a file open is to open it with:
|
||||
</p><!-- l. 1 --><p class='indent'>
|
||||
</p>
|
||||
<pre class='fancyvrb' id='fancyvrb52'><a id='x1-42004r1'></a><span class='ecrm-0500'>1</span><span class='ectt-1000'>tail -f</span></pre>
|
||||
<!-- l. 1368 --><p class='indent'> This function changes the status of the task (a task is the kernel data structure
|
||||
<!-- l. 1363 --><p class='indent'> This function changes the status of the task (a task is the kernel data structure
|
||||
which holds information about a process and the system call it is in, if any) to
|
||||
<code> <span class='ectt-1000'>TASK_INTERRUPTIBLE</span>
|
||||
</code>, which means that the task will not run until it is woken up somehow, and adds it to
|
||||
WaitQ, the queue of tasks waiting to access the file. Then, the function calls the
|
||||
scheduler to context switch to a different process, one which has some use for the
|
||||
CPU.
|
||||
|
||||
|
||||
|
||||
</p><!-- l. 1372 --><p class='indent'> When a process is done with the file, it closes it, and
|
||||
</p><!-- l. 1367 --><p class='indent'> When a process is done with the file, it closes it, and
|
||||
<code> <span class='ectt-1000'>module_close</span>
|
||||
</code> is called. That function wakes up all the processes in the queue (there’s no
|
||||
mechanism to only wake up one of them). It then returns and the process which just
|
||||
|
||||
|
||||
|
||||
closed the file can continue to run. In time, the scheduler decides that that
|
||||
process has had enough and gives control of the CPU to another process.
|
||||
Eventually, one of the processes which was in the queue will be given control
|
||||
of the CPU by the scheduler. It starts at the point right after the call to
|
||||
<code> <span class='ectt-1000'>module_interruptible_sleep_on</span>
|
||||
</code>.
|
||||
</p><!-- l. 1379 --><p class='indent'> This means that the process is still in kernel mode - as far as the process
|
||||
</p><!-- l. 1374 --><p class='indent'> This means that the process is still in kernel mode - as far as the process
|
||||
is concerned, it issued the open system call and the system call has not
|
||||
returned yet. The process does not know somebody else used the CPU for
|
||||
most of the time between the moment it issued the call and the moment it
|
||||
returned.
|
||||
</p><!-- l. 1382 --><p class='indent'> It can then proceed to set a global variable to tell all the other processes that the
|
||||
</p><!-- l. 1377 --><p class='indent'> It can then proceed to set a global variable to tell all the other processes that the
|
||||
file is still open and go on with its life. When the other processes get a piece of the
|
||||
CPU, they’ll see that global variable and go back to sleep.
|
||||
</p><!-- l. 1385 --><p class='indent'> So we will use <code> <span class='ectt-1000'>tail -f</span>
|
||||
</p><!-- l. 1380 --><p class='indent'> So we will use <code> <span class='ectt-1000'>tail -f</span>
|
||||
</code> to keep the file open in the background, while trying to access it with another
|
||||
process (again in the background, so that we need not switch to a different vt). As
|
||||
soon as the first background process is killed with kill %1 , the second is woken up, is
|
||||
able to access the file and finally terminates.
|
||||
</p><!-- l. 1388 --><p class='indent'> To make our life more interesting, <code> <span class='ectt-1000'>module_close</span>
|
||||
</p><!-- l. 1383 --><p class='indent'> To make our life more interesting, <code> <span class='ectt-1000'>module_close</span>
|
||||
</code> does not have a monopoly on waking up the processes which wait to access the file.
|
||||
A signal, such as <span class='ecti-1000'>Ctrl +c </span>(<span class='ecbx-1000'>SIGINT</span>) can also wake up a process. This is because we
|
||||
used <code> <span class='ectt-1000'>module_interruptible_sleep_on</span>
|
||||
</code>. We could have used <code> <span class='ectt-1000'>module_sleep_on</span>
|
||||
</code> instead, but that would have resulted in extremely angry users whose <span class='ecti-1000'>Ctrl+c</span>’s are
|
||||
ignored.
|
||||
</p><!-- l. 1392 --><p class='indent'> In that case, we want to return with
|
||||
</p><!-- l. 1387 --><p class='indent'> In that case, we want to return with
|
||||
<code> <span class='ectt-1000'>-EINTR</span>
|
||||
</code> immediately. This is important so users can, for example, kill the process before it
|
||||
receives the file.
|
||||
</p><!-- l. 1394 --><p class='indent'> There is one more point to remember. Some times processes don’t want to sleep, they want
|
||||
</p><!-- l. 1389 --><p class='indent'> There is one more point to remember. Some times processes don’t want to sleep, they want
|
||||
either to get what they want immediately, or to be told it cannot be done. Such processes
|
||||
use the <code> <span class='ectt-1000'>O_NONBLOCK</span>
|
||||
</code> flag when opening the file. The kernel is supposed to respond by returning with the error
|
||||
@ -3462,7 +3457,7 @@ $ cat_nonblock /proc/sleep
|
||||
Last input:
|
||||
$
|
||||
</pre>
|
||||
<!-- l. 1419 --><p class='nopar'>
|
||||
<!-- l. 1414 --><p class='nopar'>
|
||||
</p><!-- l. 1 --><p class='indent'>
|
||||
</p>
|
||||
<pre class='fancyvrb' id='fancyvrb53'><a id='x1-42018r1'></a><span class='ecrm-0500'>1</span><span id='textcolor1569'><span class='ectt-0800'>/*</span></span>
|
||||
@ -3741,14 +3736,14 @@ $
|
||||
<a id='x1-42558r57'></a><span class='ecrm-0500'>57</span>
|
||||
<a id='x1-42560r58'></a><span class='ecrm-0500'>58</span><span class='ectt-0800'> </span><span id='textcolor1805'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> 0;</span>
|
||||
<a id='x1-42562r59'></a><span class='ecrm-0500'>59</span><span class='ectt-0800'>}</span></pre>
|
||||
<!-- l. 1425 --><p class='noindent'>
|
||||
<!-- l. 1420 --><p class='noindent'>
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='completions'><span class='titlemark'>11.2 </span> <a id='x1-4300011.2'></a>Completions</h4>
|
||||
<!-- l. 1427 --><p class='noindent'>Sometimes one thing should happen before another within a module having multiple threads.
|
||||
<!-- l. 1422 --><p class='noindent'>Sometimes one thing should happen before another within a module having multiple threads.
|
||||
Rather than using <code> <span class='ectt-1000'>/bin/sleep</span>
|
||||
</code> commands, the kernel has another way to do this which allows timeouts or
|
||||
interrupts to also happen.
|
||||
</p><!-- l. 1430 --><p class='indent'> In the following example two threads are started, but one needs to start before
|
||||
</p><!-- l. 1425 --><p class='indent'> In the following example two threads are started, but one needs to start before
|
||||
another.
|
||||
</p><!-- l. 1 --><p class='indent'>
|
||||
|
||||
@ -3831,31 +3826,31 @@ another.
|
||||
<a id='x1-43149r74'></a><span class='ecrm-0500'>74</span>
|
||||
<a id='x1-43151r75'></a><span class='ecrm-0500'>75</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor1857'><span class='ectt-0800'>"Completions example"</span></span><span class='ectt-0800'>);</span>
|
||||
<a id='x1-43153r76'></a><span class='ecrm-0500'>76</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor1858'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
||||
<!-- l. 1434 --><p class='indent'> The <code> <span class='ectt-1000'>machine</span>
|
||||
<!-- l. 1429 --><p class='indent'> The <code> <span class='ectt-1000'>machine</span>
|
||||
</code> structure stores the completion states for the two threads. At the exit
|
||||
point of each thread the respective completion state is updated, and
|
||||
<code> <span class='ectt-1000'>wait_for_completion</span>
|
||||
</code> is used by the flywheel thread to ensure that it does not begin prematurely.
|
||||
</p><!-- l. 1437 --><p class='indent'> So even though <code> <span class='ectt-1000'>flywheel_thread</span>
|
||||
</p><!-- l. 1432 --><p class='indent'> So even though <code> <span class='ectt-1000'>flywheel_thread</span>
|
||||
</code> is started first you should notice if you load this module and run
|
||||
<code> <span class='ectt-1000'>dmesg</span>
|
||||
</code> that turning the crank always happens first because the flywheel thread waits for it
|
||||
to complete.
|
||||
</p><!-- l. 1439 --><p class='indent'> There are other variations upon the
|
||||
</p><!-- l. 1434 --><p class='indent'> There are other variations upon the
|
||||
<code> <span class='ectt-1000'>wait_for_completion</span>
|
||||
</code> function, which include timeouts or being interrupted, but this basic mechanism is
|
||||
enough for many common situations without adding a lot of complexity.
|
||||
</p><!-- l. 1441 --><p class='noindent'>
|
||||
</p><!-- l. 1436 --><p class='noindent'>
|
||||
</p>
|
||||
<h3 class='sectionHead' id='avoiding-collisions-and-deadlocks'><span class='titlemark'>12 </span> <a id='x1-4400012'></a>Avoiding Collisions and Deadlocks</h3>
|
||||
<!-- l. 1443 --><p class='noindent'>If processes running on different CPUs or in different threads try to access the same
|
||||
<!-- l. 1438 --><p class='noindent'>If processes running on different CPUs or in different threads try to access the same
|
||||
memory, then it is possible that strange things can happen or your system can lock
|
||||
up. To avoid this, various types of mutual exclusion kernel functions are available.
|
||||
These indicate if a section of code is "locked" or "unlocked" so that simultaneous
|
||||
attempts to run it can not happen.
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='mutex'><span class='titlemark'>12.1 </span> <a id='x1-4500012.1'></a>Mutex</h4>
|
||||
<!-- l. 1448 --><p class='noindent'>You can use kernel mutexes (mutual exclusions) in much the same manner that you
|
||||
<!-- l. 1443 --><p class='noindent'>You can use kernel mutexes (mutual exclusions) in much the same manner that you
|
||||
might deploy them in userland. This may be all that is needed to avoid collisions in
|
||||
most cases.
|
||||
</p><!-- l. 1 --><p class='indent'>
|
||||
@ -3901,10 +3896,10 @@ most cases.
|
||||
<a id='x1-45078r39'></a><span class='ecrm-0500'>39</span>
|
||||
<a id='x1-45080r40'></a><span class='ecrm-0500'>40</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor1900'><span class='ectt-0800'>"Mutex example"</span></span><span class='ectt-0800'>);</span>
|
||||
<a id='x1-45082r41'></a><span class='ecrm-0500'>41</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor1901'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
||||
<!-- l. 1453 --><p class='noindent'>
|
||||
<!-- l. 1448 --><p class='noindent'>
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='spinlocks'><span class='titlemark'>12.2 </span> <a id='x1-4600012.2'></a>Spinlocks</h4>
|
||||
<!-- l. 1455 --><p class='noindent'>As the name suggests, spinlocks lock up the CPU that the code is running on,
|
||||
<!-- l. 1450 --><p class='noindent'>As the name suggests, spinlocks lock up the CPU that the code is running on,
|
||||
taking 100% of its resources. Because of this you should only use the spinlock
|
||||
|
||||
|
||||
@ -3912,7 +3907,7 @@ taking 100% of its resources. Because of this you should only use the spinlock
|
||||
mechanism around code which is likely to take no more than a few milliseconds to
|
||||
run and so will not noticeably slow anything down from the user’s point of
|
||||
view.
|
||||
</p><!-- l. 1458 --><p class='indent'> The example here is <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>"irq safe"</span></span></span> in that if interrupts happen during the lock then
|
||||
</p><!-- l. 1453 --><p class='indent'> The example here is <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>"irq safe"</span></span></span> in that if interrupts happen during the lock then
|
||||
they will not be forgotten and will activate when the unlock happens, using the
|
||||
<code> <span class='ectt-1000'>flags</span>
|
||||
</code> variable to retain their state.
|
||||
@ -3981,10 +3976,10 @@ they will not be forgotten and will activate when the unlock happens, using the
|
||||
<a id='x1-46123r61'></a><span class='ecrm-0500'>61</span>
|
||||
<a id='x1-46125r62'></a><span class='ecrm-0500'>62</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor1958'><span class='ectt-0800'>"Spinlock example"</span></span><span class='ectt-0800'>);</span>
|
||||
<a id='x1-46127r63'></a><span class='ecrm-0500'>63</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor1959'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
||||
<!-- l. 1462 --><p class='noindent'>
|
||||
<!-- l. 1457 --><p class='noindent'>
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='read-and-write-locks'><span class='titlemark'>12.3 </span> <a id='x1-4700012.3'></a>Read and write locks</h4>
|
||||
<!-- l. 1464 --><p class='noindent'>Read and write locks are specialised kinds of spinlocks so that you can exclusively
|
||||
<!-- l. 1459 --><p class='noindent'>Read and write locks are specialised kinds of spinlocks so that you can exclusively
|
||||
read from something or write to something. Like the earlier spinlocks example, the
|
||||
one below shows an "irq safe" situation in which if other functions were triggered
|
||||
from irqs which might also read and write to whatever you are concerned with
|
||||
@ -4049,14 +4044,14 @@ module.
|
||||
<a id='x1-47106r53'></a><span class='ecrm-0500'>53</span>
|
||||
<a id='x1-47108r54'></a><span class='ecrm-0500'>54</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor2007'><span class='ectt-0800'>"Read/Write locks example"</span></span><span class='ectt-0800'>);</span>
|
||||
<a id='x1-47110r55'></a><span class='ecrm-0500'>55</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor2008'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
||||
<!-- l. 1470 --><p class='indent'> Of course, if you know for sure that there are no functions triggered by irqs
|
||||
<!-- l. 1465 --><p class='indent'> Of course, if you know for sure that there are no functions triggered by irqs
|
||||
which could possibly interfere with your logic then you can use the simpler
|
||||
<code> <span class='ectt-1000'>read_lock(&myrwlock)</span>
|
||||
</code> and <code> <span class='ectt-1000'>read_unlock(&myrwlock)</span>
|
||||
</code> or the corresponding write functions.
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='atomic-operations'><span class='titlemark'>12.4 </span> <a id='x1-4800012.4'></a>Atomic operations</h4>
|
||||
<!-- l. 1473 --><p class='noindent'>If you are doing simple arithmetic: adding, subtracting or bitwise operations, then
|
||||
<!-- l. 1468 --><p class='noindent'>If you are doing simple arithmetic: adding, subtracting or bitwise operations, then
|
||||
there is another way in the multi-CPU and multi-hyperthreaded world to stop other
|
||||
parts of the system from messing with your mojo. By using atomic operations you
|
||||
can be confident that your addition, subtraction or bit flip did actually happen
|
||||
@ -4141,7 +4136,7 @@ below.
|
||||
|
||||
|
||||
|
||||
<!-- l. 1479 --><p class='indent'> Before the C11 standard adopts the built-in atomic types, the kernel already
|
||||
<!-- l. 1474 --><p class='indent'> Before the C11 standard adopts the built-in atomic types, the kernel already
|
||||
provided a small set of atomic types by using a bunch of tricky architecture-specific
|
||||
codes. Implementing the atomic types by C11 atomics may allow the kernel to throw
|
||||
away the architecture-specific codes and letting the kernel code be more friendly to
|
||||
@ -4154,21 +4149,21 @@ For further details, see: </p>
|
||||
<li class='itemize'><a href='https://lwn.net/Articles/691128/'>Time to move to C11 atomics?</a>
|
||||
</li>
|
||||
<li class='itemize'><a href='https://lwn.net/Articles/698315/'>Atomic usage patterns in the kernel</a></li></ul>
|
||||
<!-- l. 1490 --><p class='noindent'>
|
||||
<!-- l. 1485 --><p class='noindent'>
|
||||
</p>
|
||||
<h3 class='sectionHead' id='replacing-print-macros'><span class='titlemark'>13 </span> <a id='x1-4900013'></a>Replacing Print Macros</h3>
|
||||
<!-- l. 1492 --><p class='noindent'>
|
||||
<!-- l. 1487 --><p class='noindent'>
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='replacement'><span class='titlemark'>13.1 </span> <a id='x1-5000013.1'></a>Replacement</h4>
|
||||
<!-- l. 1494 --><p class='noindent'>In Section <a href='#x1-80042'>2<!-- tex4ht:ref: sec:using_x --></a>, I said that X Window System and kernel module programming do not
|
||||
<!-- l. 1489 --><p class='noindent'>In Section <a href='#x1-80042'>2<!-- tex4ht:ref: sec:using_x --></a>, I said that X Window System and kernel module programming do not
|
||||
mix. That is true for developing kernel modules. But in actual use, you want to be
|
||||
able to send messages to whichever tty the command to load the module came
|
||||
from.
|
||||
</p><!-- l. 1498 --><p class='indent'> "tty" is an abbreviation of <span class='ecti-1000'>teletype</span>: originally a combination keyboard-printer
|
||||
</p><!-- l. 1493 --><p class='indent'> "tty" is an abbreviation of <span class='ecti-1000'>teletype</span>: originally a combination keyboard-printer
|
||||
used to communicate with a Unix system, and today an abstraction for the text
|
||||
stream used for a Unix program, whether it is a physical terminal, an xterm on an X
|
||||
display, a network connection used with ssh, etc.
|
||||
</p><!-- l. 1500 --><p class='indent'> The way this is done is by using current, a pointer to the currently running task,
|
||||
</p><!-- l. 1495 --><p class='indent'> The way this is done is by using current, a pointer to the currently running task,
|
||||
to get the current task’s tty structure. Then, we look inside that tty structure to find
|
||||
a pointer to a string write function, which we use to write a string to the
|
||||
tty.
|
||||
@ -4251,16 +4246,16 @@ tty.
|
||||
|
||||
|
||||
|
||||
<!-- l. 1505 --><p class='noindent'>
|
||||
<!-- l. 1500 --><p class='noindent'>
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='flashing-keyboard-leds'><span class='titlemark'>13.2 </span> <a id='x1-5100013.2'></a>Flashing keyboard LEDs</h4>
|
||||
<!-- l. 1507 --><p class='noindent'>In certain conditions, you may desire a simpler and more direct way to communicate
|
||||
<!-- l. 1502 --><p class='noindent'>In certain conditions, you may desire a simpler and more direct way to communicate
|
||||
to the external world. Flashing keyboard LEDs can be such a solution: It is an
|
||||
immediate way to attract attention or to display a status condition. Keyboard LEDs
|
||||
are present on every hardware, they are always visible, they do not need any setup,
|
||||
and their use is rather simple and non-intrusive, compared to writing to a tty or a
|
||||
file.
|
||||
</p><!-- l. 1511 --><p class='indent'> From v4.14 to v4.15, the timer API made a series of changes
|
||||
</p><!-- l. 1506 --><p class='indent'> From v4.14 to v4.15, the timer API made a series of changes
|
||||
to improve memory safety. A buffer overflow in the area of a
|
||||
<code> <span class='ectt-1000'>timer_list</span>
|
||||
</code> structure may be able to overwrite the
|
||||
@ -4283,7 +4278,7 @@ to use a unique prototype to separate from the cluster that takes an
|
||||
<code> <span class='ectt-1000'>container_of</span>
|
||||
</code> macro instead of the <code> <span id='textcolor2142'><span class='ectt-1000'>unsigned</span></span><span class='ectt-1000'> </span><span id='textcolor2143'><span class='ectt-1000'>long</span></span>
|
||||
</code> value.
|
||||
</p><!-- l. 1519 --><p class='indent'> Before Linux v4.14, <code> <span class='ectt-1000'>setup_timer</span>
|
||||
</p><!-- l. 1514 --><p class='indent'> Before Linux v4.14, <code> <span class='ectt-1000'>setup_timer</span>
|
||||
</code> was used to initialize the timer and the
|
||||
<code> <span class='ectt-1000'>timer_list</span>
|
||||
</code> structure looked like:
|
||||
@ -4298,7 +4293,7 @@ to use a unique prototype to separate from the cluster that takes an
|
||||
<a id='x1-51039r8'></a><span class='ecrm-0500'>8</span>
|
||||
<a id='x1-51041r9'></a><span class='ecrm-0500'>9</span><span id='textcolor2153'><span class='ectt-0800'>void</span></span><span class='ectt-0800'> setup_timer(</span><span id='textcolor2154'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> timer_list *timer, </span><span id='textcolor2155'><span class='ectt-0800'>void</span></span><span class='ectt-0800'> (*callback)(</span><span id='textcolor2156'><span class='ectt-0800'>unsigned</span></span><span class='ectt-0800'> </span><span id='textcolor2157'><span class='ectt-0800'>long</span></span><span class='ectt-0800'>),</span>
|
||||
<a id='x1-51043r10'></a><span class='ecrm-0500'>10</span><span class='ectt-0800'> </span><span id='textcolor2158'><span class='ectt-0800'>unsigned</span></span><span class='ectt-0800'> </span><span id='textcolor2159'><span class='ectt-0800'>long</span></span><span class='ectt-0800'> data);</span></pre>
|
||||
<!-- l. 1533 --><p class='indent'> Since Linux v4.14, <code> <span class='ectt-1000'>timer_setup</span>
|
||||
<!-- l. 1528 --><p class='indent'> Since Linux v4.14, <code> <span class='ectt-1000'>timer_setup</span>
|
||||
</code> is adopted and the kernel step by step converting to
|
||||
<code> <span class='ectt-1000'>timer_setup</span>
|
||||
</code> from <code> <span class='ectt-1000'>setup_timer</span>
|
||||
@ -4312,7 +4307,7 @@ Moreover, the <code> <span class='ectt-1000'>timer_setup</span>
|
||||
</p>
|
||||
<pre class='fancyvrb' id='fancyvrb62'><a id='x1-51052r1'></a><span class='ecrm-0500'>1</span><span id='textcolor2160'><span class='ectt-0800'>void</span></span><span class='ectt-0800'> timer_setup(</span><span id='textcolor2161'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> timer_list *timer,</span>
|
||||
<a id='x1-51054r2'></a><span class='ecrm-0500'>2</span><span class='ectt-0800'> </span><span id='textcolor2162'><span class='ectt-0800'>void</span></span><span class='ectt-0800'> (*callback)(</span><span id='textcolor2163'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> timer_list *), </span><span id='textcolor2164'><span class='ectt-0800'>unsigned</span></span><span class='ectt-0800'> </span><span id='textcolor2165'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> flags);</span></pre>
|
||||
<!-- l. 1541 --><p class='indent'> The <code> <span class='ectt-1000'>setup_timer</span>
|
||||
<!-- l. 1536 --><p class='indent'> The <code> <span class='ectt-1000'>setup_timer</span>
|
||||
</code> was then removed since v4.15. As a result, the
|
||||
<code> <span class='ectt-1000'>timer_list</span>
|
||||
</code> structure had changed to the following.
|
||||
@ -4323,7 +4318,7 @@ Moreover, the <code> <span class='ectt-1000'>timer_setup</span>
|
||||
<a id='x1-51070r4'></a><span class='ecrm-0500'>4</span><span class='ectt-0800'> u32 flags;</span>
|
||||
<a id='x1-51072r5'></a><span class='ecrm-0500'>5</span><span class='ectt-0800'> </span><span id='textcolor2171'><span class='ectt-0800'>/* ... */</span></span>
|
||||
<a id='x1-51074r6'></a><span class='ecrm-0500'>6</span><span class='ectt-0800'>};</span></pre>
|
||||
<!-- l. 1552 --><p class='indent'> The following source code illustrates a minimal kernel module which, when
|
||||
<!-- l. 1547 --><p class='indent'> The following source code illustrates a minimal kernel module which, when
|
||||
loaded, starts blinking the keyboard LEDs until it is unloaded.
|
||||
</p><!-- l. 1 --><p class='indent'>
|
||||
</p>
|
||||
@ -4412,7 +4407,7 @@ loaded, starts blinking the keyboard LEDs until it is unloaded.
|
||||
<a id='x1-51240r83'></a><span class='ecrm-0500'>83</span><span class='ectt-0800'>module_exit(kbleds_cleanup);</span>
|
||||
<a id='x1-51242r84'></a><span class='ecrm-0500'>84</span>
|
||||
<a id='x1-51244r85'></a><span class='ecrm-0500'>85</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor2249'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
||||
<!-- l. 1556 --><p class='indent'> If none of the examples in this chapter fit your debugging needs,
|
||||
<!-- l. 1551 --><p class='indent'> If none of the examples in this chapter fit your debugging needs,
|
||||
there might yet be some other tricks to try. Ever wondered what
|
||||
<code> <span class='ectt-1000'>CONFIG_LL_DEBUG</span>
|
||||
</code> in <code> <span class='ectt-1000'>make menuconfig</span>
|
||||
@ -4423,25 +4418,25 @@ everything what your code does over a serial line. If you find yourself porting
|
||||
kernel to some new and former unsupported architecture, this is usually amongst the
|
||||
first things that should be implemented. Logging over a netconsole might also be
|
||||
worth a try.
|
||||
</p><!-- l. 1563 --><p class='indent'> While you have seen lots of stuff that can be used to aid debugging here, there are
|
||||
</p><!-- l. 1558 --><p class='indent'> While you have seen lots of stuff that can be used to aid debugging here, there are
|
||||
some things to be aware of. Debugging is almost always intrusive. Adding debug code
|
||||
can change the situation enough to make the bug seem to dissappear. Thus you
|
||||
should try to keep debug code to a minimum and make sure it does not show up in
|
||||
production code.
|
||||
</p><!-- l. 1567 --><p class='noindent'>
|
||||
</p><!-- l. 1562 --><p class='noindent'>
|
||||
</p>
|
||||
<h3 class='sectionHead' id='scheduling-tasks'><span class='titlemark'>14 </span> <a id='x1-5200014'></a>Scheduling Tasks</h3>
|
||||
<!-- l. 1569 --><p class='noindent'>There are two main ways of running tasks: tasklets and work queues. Tasklets are a
|
||||
<!-- l. 1564 --><p class='noindent'>There are two main ways of running tasks: tasklets and work queues. Tasklets are a
|
||||
quick and easy way of scheduling a single function to be run. For example, when
|
||||
triggered from an interrupt, whereas work queues are more complicated but also
|
||||
better suited to running multiple things in a sequence.
|
||||
|
||||
|
||||
|
||||
</p><!-- l. 1573 --><p class='noindent'>
|
||||
</p><!-- l. 1568 --><p class='noindent'>
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='tasklets'><span class='titlemark'>14.1 </span> <a id='x1-5300014.1'></a>Tasklets</h4>
|
||||
<!-- l. 1575 --><p class='noindent'>Here is an example tasklet module. The
|
||||
<!-- l. 1570 --><p class='noindent'>Here is an example tasklet module. The
|
||||
<code> <span class='ectt-1000'>tasklet_fn</span>
|
||||
</code> function runs for a few seconds and in the mean time execution of the
|
||||
<code> <span class='ectt-1000'>example_tasklet_init</span>
|
||||
@ -4492,7 +4487,7 @@ better suited to running multiple things in a sequence.
|
||||
<a id='x1-53086r42'></a><span class='ecrm-0500'>42</span>
|
||||
<a id='x1-53088r43'></a><span class='ecrm-0500'>43</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor2294'><span class='ectt-0800'>"Tasklet example"</span></span><span class='ectt-0800'>);</span>
|
||||
<a id='x1-53090r44'></a><span class='ecrm-0500'>44</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor2295'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
||||
<!-- l. 1580 --><p class='indent'> So with this example loaded <code> <span class='ectt-1000'>dmesg</span>
|
||||
<!-- l. 1575 --><p class='indent'> So with this example loaded <code> <span class='ectt-1000'>dmesg</span>
|
||||
</code> should show:
|
||||
|
||||
|
||||
@ -4504,23 +4499,23 @@ Example tasklet starts
|
||||
Example tasklet init continues...
|
||||
Example tasklet ends
|
||||
</pre>
|
||||
<!-- l. 1587 --><p class='nopar'>Although tasklet is easy to use, it comes with several defators, and developers are
|
||||
<!-- l. 1582 --><p class='nopar'>Although tasklet is easy to use, it comes with several defators, and developers are
|
||||
discussing about getting rid of tasklet in linux kernel. The tasklet callback
|
||||
runs in atomic context, inside a software interrupt, meaning that it cannot
|
||||
sleep or access user-space data, so not all work can be done in a tasklet
|
||||
handler. Also, the kernel only allows one instance of any given tasklet to be
|
||||
running at any given time; multiple different tasklet callbacks can run in
|
||||
parallel.
|
||||
</p><!-- l. 1592 --><p class='indent'> In recent kernels, tasklets can be replaced by workqueues, timers, or threaded
|
||||
</p><!-- l. 1587 --><p class='indent'> In recent kernels, tasklets can be replaced by workqueues, timers, or threaded
|
||||
interrupts.<span class='footnote-mark'><a href='#fn1x0' id='fn1x0-bk'><sup class='textsuperscript'>1</sup></a></span><a id='x1-53092f1'></a>
|
||||
While the removal of tasklets remains a longer-term goal, the current kernel contains more
|
||||
than a hundred uses of tasklets. Now developers are proceeding with the API changes and
|
||||
the macro <code> <span class='ectt-1000'>DECLARE_TASKLET_OLD</span>
|
||||
</code> exists for compatibility. For further information, see <a class='url' href='https://lwn.net/Articles/830964/'><span class='ectt-1000'>https://lwn.net/Articles/830964/</span></a>.
|
||||
</p><!-- l. 1598 --><p class='noindent'>
|
||||
</p><!-- l. 1593 --><p class='noindent'>
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='work-queues'><span class='titlemark'>14.2 </span> <a id='x1-5400014.2'></a>Work queues</h4>
|
||||
<!-- l. 1600 --><p class='noindent'>To add a task to the scheduler we can use a workqueue. The kernel then uses the
|
||||
<!-- l. 1595 --><p class='noindent'>To add a task to the scheduler we can use a workqueue. The kernel then uses the
|
||||
Completely Fair Scheduler (CFS) to execute work within the queue.
|
||||
</p><!-- l. 1 --><p class='indent'>
|
||||
</p>
|
||||
@ -4557,36 +4552,36 @@ Completely Fair Scheduler (CFS) to execute work within the queue.
|
||||
<a id='x1-54062r31'></a><span class='ecrm-0500'>31</span>
|
||||
<a id='x1-54064r32'></a><span class='ecrm-0500'>32</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor2323'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span>
|
||||
<a id='x1-54066r33'></a><span class='ecrm-0500'>33</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor2324'><span class='ectt-0800'>"Workqueue example"</span></span><span class='ectt-0800'>);</span></pre>
|
||||
<!-- l. 1605 --><p class='noindent'>
|
||||
<!-- l. 1600 --><p class='noindent'>
|
||||
</p>
|
||||
<h3 class='sectionHead' id='interrupt-handlers'><span class='titlemark'>15 </span> <a id='x1-5500015'></a>Interrupt Handlers</h3>
|
||||
<!-- l. 1607 --><p class='noindent'>
|
||||
<!-- l. 1602 --><p class='noindent'>
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
<h4 class='subsectionHead' id='interrupt-handlers1'><span class='titlemark'>15.1 </span> <a id='x1-5600015.1'></a>Interrupt Handlers</h4>
|
||||
<!-- l. 1609 --><p class='noindent'>Except for the last chapter, everything we did in the kernel so far we have done as a
|
||||
<!-- l. 1604 --><p class='noindent'>Except for the last chapter, everything we did in the kernel so far we have done as a
|
||||
response to a process asking for it, either by dealing with a special file, sending an
|
||||
<code> <span class='ectt-1000'>ioctl()</span>
|
||||
</code>, or issuing a system call. But the job of the kernel is not just to respond to process
|
||||
requests. Another job, which is every bit as important, is to speak to the hardware
|
||||
connected to the machine.
|
||||
</p><!-- l. 1613 --><p class='indent'> There are two types of interaction between the CPU and the rest of the
|
||||
</p><!-- l. 1608 --><p class='indent'> There are two types of interaction between the CPU and the rest of the
|
||||
computer’s hardware. The first type is when the CPU gives orders to the hardware,
|
||||
the order is when the hardware needs to tell the CPU something. The second, called
|
||||
interrupts, is much harder to implement because it has to be dealt with when
|
||||
convenient for the hardware, not the CPU. Hardware devices typically have a very
|
||||
small amount of RAM, and if you do not read their information when available, it is
|
||||
lost.
|
||||
</p><!-- l. 1618 --><p class='indent'> Under Linux, hardware interrupts are called IRQ’s (Interrupt ReQuests). There
|
||||
</p><!-- l. 1613 --><p class='indent'> Under Linux, hardware interrupts are called IRQ’s (Interrupt ReQuests). There
|
||||
are two types of IRQ’s, short and long. A short IRQ is one which is expected to take
|
||||
a very short period of time, during which the rest of the machine will be blocked and
|
||||
no other interrupts will be handled. A long IRQ is one which can take longer, and
|
||||
during which other interrupts may occur (but not interrupts from the same
|
||||
device). If at all possible, it is better to declare an interrupt handler to be
|
||||
long.
|
||||
</p><!-- l. 1624 --><p class='indent'> When the CPU receives an interrupt, it stops whatever it is doing (unless it is
|
||||
</p><!-- l. 1619 --><p class='indent'> When the CPU receives an interrupt, it stops whatever it is doing (unless it is
|
||||
processing a more important interrupt, in which case it will deal with this one only
|
||||
when the more important one is done), saves certain parameters on the stack and
|
||||
calls the interrupt handler. This means that certain things are not allowed in the
|
||||
@ -4598,10 +4593,10 @@ heavy work deferred from an interrupt handler. Historically, BH (Linux
|
||||
naming for <span class='ecti-1000'>Bottom Halves</span>) statistically book-keeps the deferred functions.
|
||||
<span class='ecbx-1000'>Softirq </span>and its higher level abstraction, <span class='ecbx-1000'>Tasklet</span>, replace BH since Linux
|
||||
2.3.
|
||||
</p><!-- l. 1634 --><p class='indent'> The way to implement this is to call
|
||||
</p><!-- l. 1629 --><p class='indent'> The way to implement this is to call
|
||||
<code> <span class='ectt-1000'>request_irq()</span>
|
||||
</code> to get your interrupt handler called when the relevant IRQ is received.
|
||||
</p><!-- l. 1636 --><p class='indent'> In practice IRQ handling can be a bit more complex. Hardware is often
|
||||
</p><!-- l. 1631 --><p class='indent'> In practice IRQ handling can be a bit more complex. Hardware is often
|
||||
designed in a way that chains two interrupt controllers, so that all the IRQs
|
||||
from interrupt controller B are cascaded to a certain IRQ from interrupt
|
||||
controller A. Of course, that requires that the kernel finds out which IRQ it
|
||||
@ -4618,7 +4613,7 @@ need to solve another truckload of problems. It is not enough to know if a
|
||||
certain IRQs has happened, it’s also important to know what CPU(s) it was
|
||||
for. People still interested in more details, might want to refer to "APIC"
|
||||
now.
|
||||
</p><!-- l. 1645 --><p class='indent'> This function receives the IRQ number, the name of the function,
|
||||
</p><!-- l. 1640 --><p class='indent'> This function receives the IRQ number, the name of the function,
|
||||
flags, a name for <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>/proc/interrupts</span></span></span> and a parameter to be passed to the
|
||||
interrupt handler. Usually there is a certain number of IRQs available.
|
||||
How many IRQs there are is hardware-dependent. The flags can include
|
||||
@ -4628,16 +4623,16 @@ How many IRQs there are is hardware-dependent. The flags can include
|
||||
<code> <span class='ectt-1000'>SA_INTERRUPT</span>
|
||||
</code> to indicate this is a fast interrupt. This function will only succeed if there is not
|
||||
already a handler on this IRQ, or if you are both willing to share.
|
||||
</p><!-- l. 1651 --><p class='noindent'>
|
||||
</p><!-- l. 1646 --><p class='noindent'>
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='detecting-button-presses'><span class='titlemark'>15.2 </span> <a id='x1-5700015.2'></a>Detecting button presses</h4>
|
||||
<!-- l. 1653 --><p class='noindent'>Many popular single board computers, such as Raspberry Pi or Beagleboards, have a
|
||||
<!-- l. 1648 --><p class='noindent'>Many popular single board computers, such as Raspberry Pi or Beagleboards, have a
|
||||
bunch of GPIO pins. Attaching buttons to those and then having a button press do
|
||||
something is a classic case in which you might need to use interrupts, so that instead
|
||||
of having the CPU waste time and battery power polling for a change in input state,
|
||||
it is better for the input to trigger the CPU to then run a particular handling
|
||||
function.
|
||||
</p><!-- l. 1657 --><p class='indent'> Here is an example where buttons are connected to GPIO numbers 17 and 18 and
|
||||
</p><!-- l. 1652 --><p class='indent'> Here is an example where buttons are connected to GPIO numbers 17 and 18 and
|
||||
an LED is connected to GPIO 4. You can change those numbers to whatever is
|
||||
appropriate for your board.
|
||||
</p><!-- l. 1 --><p class='indent'>
|
||||
@ -4786,14 +4781,14 @@ appropriate for your board.
|
||||
<a id='x1-57284r142'></a><span class='ecrm-0500'>142</span>
|
||||
<a id='x1-57286r143'></a><span class='ecrm-0500'>143</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor2431'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span>
|
||||
<a id='x1-57288r144'></a><span class='ecrm-0500'>144</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor2432'><span class='ectt-0800'>"Handle some GPIO interrupts"</span></span><span class='ectt-0800'>);</span></pre>
|
||||
<!-- l. 1662 --><p class='noindent'>
|
||||
<!-- l. 1657 --><p class='noindent'>
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='bottom-half'><span class='titlemark'>15.3 </span> <a id='x1-5800015.3'></a>Bottom Half</h4>
|
||||
<!-- l. 1664 --><p class='noindent'>Suppose you want to do a bunch of stuff inside of an interrupt routine. A common
|
||||
<!-- l. 1659 --><p class='noindent'>Suppose you want to do a bunch of stuff inside of an interrupt routine. A common
|
||||
way to do that without rendering the interrupt unavailable for a significant duration
|
||||
is to combine it with a tasklet. This pushes the bulk of the work off into the
|
||||
scheduler.
|
||||
</p><!-- l. 1668 --><p class='indent'> The example below modifies the previous example to also run an additional task
|
||||
</p><!-- l. 1663 --><p class='indent'> The example below modifies the previous example to also run an additional task
|
||||
when an interrupt is triggered.
|
||||
</p><!-- l. 1 --><p class='indent'>
|
||||
|
||||
@ -4967,19 +4962,19 @@ when an interrupt is triggered.
|
||||
<a id='x1-58330r165'></a><span class='ecrm-0500'>165</span>
|
||||
<a id='x1-58332r166'></a><span class='ecrm-0500'>166</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor2560'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span>
|
||||
<a id='x1-58334r167'></a><span class='ecrm-0500'>167</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor2561'><span class='ectt-0800'>"Interrupt with top and bottom half"</span></span><span class='ectt-0800'>);</span></pre>
|
||||
<!-- l. 1672 --><p class='noindent'>
|
||||
<!-- l. 1667 --><p class='noindent'>
|
||||
</p>
|
||||
<h3 class='sectionHead' id='crypto'><span class='titlemark'>16 </span> <a id='x1-5900016'></a>Crypto</h3>
|
||||
<!-- l. 1674 --><p class='noindent'>At the dawn of the internet, everybody trusted everybody completely…but that did
|
||||
<!-- l. 1669 --><p class='noindent'>At the dawn of the internet, everybody trusted everybody completely…but that did
|
||||
not work out so well. When this guide was originally written, it was a more innocent
|
||||
era in which almost nobody actually gave a damn about crypto - least of all kernel
|
||||
developers. That is certainly no longer the case now. To handle crypto stuff, the
|
||||
kernel has its own API enabling common methods of encryption, decryption and your
|
||||
favourite hash functions.
|
||||
</p><!-- l. 1679 --><p class='noindent'>
|
||||
</p><!-- l. 1674 --><p class='noindent'>
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='hash-functions'><span class='titlemark'>16.1 </span> <a id='x1-6000016.1'></a>Hash functions</h4>
|
||||
<!-- l. 1682 --><p class='noindent'>Calculating and checking the hashes of things is a common operation. Here is a
|
||||
<!-- l. 1677 --><p class='noindent'>Calculating and checking the hashes of things is a common operation. Here is a
|
||||
demonstration of how to calculate a sha256 hash within a kernel module.
|
||||
</p><!-- l. 1 --><p class='indent'>
|
||||
</p>
|
||||
@ -5047,20 +5042,20 @@ demonstration of how to calculate a sha256 hash within a kernel module.
|
||||
<a id='x1-60124r62'></a><span class='ecrm-0500'>62</span>
|
||||
<a id='x1-60126r63'></a><span class='ecrm-0500'>63</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor2613'><span class='ectt-0800'>"sha256 hash test"</span></span><span class='ectt-0800'>);</span>
|
||||
<a id='x1-60128r64'></a><span class='ecrm-0500'>64</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor2614'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
||||
<!-- l. 1687 --><p class='indent'> Install the module:
|
||||
<!-- l. 1682 --><p class='indent'> Install the module:
|
||||
</p><!-- l. 1 --><p class='indent'>
|
||||
</p>
|
||||
<pre class='fancyvrb' id='fancyvrb70'><a id='x1-60132r1'></a><span class='ecrm-0500'>1</span><span class='ectt-1000'>sudo insmod cryptosha256.ko</span>
|
||||
<a id='x1-60134r2'></a><span class='ecrm-0500'>2</span><span class='ectt-1000'>sudo dmesg</span></pre>
|
||||
<!-- l. 1694 --><p class='indent'> And you should see that the hash was calculated for the test string.
|
||||
</p><!-- l. 1696 --><p class='indent'> Finally, remove the test module:
|
||||
<!-- l. 1689 --><p class='indent'> And you should see that the hash was calculated for the test string.
|
||||
</p><!-- l. 1691 --><p class='indent'> Finally, remove the test module:
|
||||
</p><!-- l. 1 --><p class='indent'>
|
||||
</p>
|
||||
<pre class='fancyvrb' id='fancyvrb71'><a id='x1-60137r1'></a><span class='ecrm-0500'>1</span><span class='ectt-1000'>sudo rmmod cryptosha256</span></pre>
|
||||
<!-- l. 1702 --><p class='noindent'>
|
||||
<!-- l. 1697 --><p class='noindent'>
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='symmetric-key-encryption'><span class='titlemark'>16.2 </span> <a id='x1-6100016.2'></a>Symmetric key encryption</h4>
|
||||
<!-- l. 1704 --><p class='noindent'>Here is an example of symmetrically encrypting a string using the AES algorithm
|
||||
<!-- l. 1699 --><p class='noindent'>Here is an example of symmetrically encrypting a string using the AES algorithm
|
||||
and a password.
|
||||
</p><!-- l. 1 --><p class='indent'>
|
||||
|
||||
@ -5265,10 +5260,10 @@ and a password.
|
||||
<a id='x1-61392r196'></a><span class='ecrm-0500'>196</span>
|
||||
<a id='x1-61394r197'></a><span class='ecrm-0500'>197</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor2766'><span class='ectt-0800'>"Symmetric key encryption example"</span></span><span class='ectt-0800'>);</span>
|
||||
<a id='x1-61396r198'></a><span class='ecrm-0500'>198</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor2767'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
||||
<!-- l. 1708 --><p class='noindent'>
|
||||
<!-- l. 1703 --><p class='noindent'>
|
||||
</p>
|
||||
<h3 class='sectionHead' id='standardizing-the-interfaces-the-device-model'><span class='titlemark'>17 </span> <a id='x1-6200017'></a>Standardizing the interfaces: The Device Model</h3>
|
||||
<!-- l. 1710 --><p class='noindent'>Up to this point we have seen all kinds of modules doing all kinds of things, but there
|
||||
<!-- l. 1705 --><p class='noindent'>Up to this point we have seen all kinds of modules doing all kinds of things, but there
|
||||
was no consistency in their interfaces with the rest of the kernel. To impose some
|
||||
consistency such that there is at minimum a standardized way to start, suspend and
|
||||
resume a device a device model was added. An example is shown below, and you can
|
||||
@ -5375,13 +5370,13 @@ functions.
|
||||
<a id='x1-62194r97'></a><span class='ecrm-0500'>97</span>
|
||||
<a id='x1-62196r98'></a><span class='ecrm-0500'>98</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor2842'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span>
|
||||
<a id='x1-62198r99'></a><span class='ecrm-0500'>99</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor2843'><span class='ectt-0800'>"Linux Device Model example"</span></span><span class='ectt-0800'>);</span></pre>
|
||||
<!-- l. 1716 --><p class='noindent'>
|
||||
<!-- l. 1711 --><p class='noindent'>
|
||||
</p>
|
||||
<h3 class='sectionHead' id='optimizations'><span class='titlemark'>18 </span> <a id='x1-6300018'></a>Optimizations</h3>
|
||||
<!-- l. 1718 --><p class='noindent'>
|
||||
<!-- l. 1713 --><p class='noindent'>
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='likely-and-unlikely-conditions'><span class='titlemark'>18.1 </span> <a id='x1-6400018.1'></a>Likely and Unlikely conditions</h4>
|
||||
<!-- l. 1720 --><p class='noindent'>Sometimes you might want your code to run as quickly as possible,
|
||||
<!-- l. 1715 --><p class='noindent'>Sometimes you might want your code to run as quickly as possible,
|
||||
especially if it is handling an interrupt or doing something which might
|
||||
cause noticeable latency. If your code contains boolean conditions and if
|
||||
you know that the conditions are almost always likely to evaluate as either
|
||||
@ -5403,43 +5398,43 @@ to succeed.
|
||||
|
||||
|
||||
|
||||
<!-- l. 1734 --><p class='indent'> When the <code> <span class='ectt-1000'>unlikely</span>
|
||||
<!-- l. 1729 --><p class='indent'> When the <code> <span class='ectt-1000'>unlikely</span>
|
||||
</code> macro is used, the compiler alters its machine instruction output, so that it
|
||||
continues along the false branch and only jumps if the condition is true. That
|
||||
avoids flushing the processor pipeline. The opposite happens if you use the
|
||||
<code> <span class='ectt-1000'>likely</span>
|
||||
</code> macro.
|
||||
</p><!-- l. 1738 --><p class='noindent'>
|
||||
</p><!-- l. 1733 --><p class='noindent'>
|
||||
</p>
|
||||
<h3 class='sectionHead' id='common-pitfalls'><span class='titlemark'>19 </span> <a id='x1-6500019'></a>Common Pitfalls</h3>
|
||||
<!-- l. 1741 --><p class='noindent'>
|
||||
<!-- l. 1736 --><p class='noindent'>
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='using-standard-libraries'><span class='titlemark'>19.1 </span> <a id='x1-6600019.1'></a>Using standard libraries</h4>
|
||||
<!-- l. 1743 --><p class='noindent'>You can not do that. In a kernel module, you can only use kernel functions which are
|
||||
<!-- l. 1738 --><p class='noindent'>You can not do that. In a kernel module, you can only use kernel functions which are
|
||||
the functions you can see in <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>/proc/kallsyms</span></span></span>.
|
||||
</p><!-- l. 1746 --><p class='noindent'>
|
||||
</p><!-- l. 1741 --><p class='noindent'>
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='disabling-interrupts'><span class='titlemark'>19.2 </span> <a id='x1-6700019.2'></a>Disabling interrupts</h4>
|
||||
<!-- l. 1748 --><p class='noindent'>You might need to do this for a short time and that is OK, but if you do not enable
|
||||
<!-- l. 1743 --><p class='noindent'>You might need to do this for a short time and that is OK, but if you do not enable
|
||||
them afterwards, your system will be stuck and you will have to power it
|
||||
off.
|
||||
</p><!-- l. 1750 --><p class='noindent'>
|
||||
</p><!-- l. 1745 --><p class='noindent'>
|
||||
</p>
|
||||
<h3 class='sectionHead' id='where-to-go-from-here'><span class='titlemark'>20 </span> <a id='x1-6800020'></a>Where To Go From Here?</h3>
|
||||
<!-- l. 1752 --><p class='noindent'>For people seriously interested in kernel programming, I recommend <a href='https://kernelnewbies.org'>kernelnewbies.org</a>
|
||||
<!-- l. 1747 --><p class='noindent'>For people seriously interested in kernel programming, I recommend <a href='https://kernelnewbies.org'>kernelnewbies.org</a>
|
||||
and the <a href='https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/Documentation'>Documentation</a> subdirectory within the kernel source code which is not
|
||||
always easy to understand but can be a starting point for further investigation. Also,
|
||||
as Linus Torvalds said, the best way to learn the kernel is to read the source code
|
||||
yourself.
|
||||
</p><!-- l. 1755 --><p class='indent'> If you would like to contribute to this guide or notice anything glaringly wrong,
|
||||
</p><!-- l. 1750 --><p class='indent'> If you would like to contribute to this guide or notice anything glaringly wrong,
|
||||
please create an issue at <a class='url' href='https://github.com/sysprog21/lkmpg'><span class='ectt-1000'>https://github.com/sysprog21/lkmpg</span></a>. Your pull requests
|
||||
will be appreciated.
|
||||
</p><!-- l. 1758 --><p class='indent'> Happy hacking!
|
||||
</p><!-- l. 1753 --><p class='indent'> Happy hacking!
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
<div class='footnotes'><!-- l. 1593 --><p class='indent'> <span class='footnote-mark'><a href='#fn1x0-bk' id='fn1x0'><sup class='textsuperscript'>1</sup></a></span><span class='ecrm-0800'>The goal of threaded interrupts is to push more of the work to separate threads, so that the
|
||||
<div class='footnotes'><!-- l. 1588 --><p class='indent'> <span class='footnote-mark'><a href='#fn1x0-bk' id='fn1x0'><sup class='textsuperscript'>1</sup></a></span><span class='ecrm-0800'>The goal of threaded interrupts is to push more of the work to separate threads, so that the
|
||||
</span><span class='ecrm-0800'>minimum needed for acknowledging an interrupt is reduced, and therefore the time spent handling
|
||||
</span><span class='ecrm-0800'>the interrupt (where it can’t handle any other interrupts at the same time) is reduced. See</span>
|
||||
<a class='url' href='https://lwn.net/Articles/302043/'><span class='ectt-0800'>https://lwn.net/Articles/302043/</span></a><span class='ecrm-0800'>.</span></p> </div>
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
<h2 class='titleHead'>The Linux Kernel Module Programming Guide</h2>
|
||||
<div class='author'><span class='ecrm-1200'>Peter Jay Salzman, Michael Burian, Ori Pomerantz, Bob Mottram, Jim Huang</span></div><br />
|
||||
<div class='date'><span class='ecrm-1200'>October 10, 2021</span></div>
|
||||
<div class='date'><span class='ecrm-1200'>October 14, 2021</span></div>
|
||||
|
||||
|
||||
|
||||
@ -3124,12 +3124,7 @@ production use. In order to keep people from doing potential harmful things
|
||||
|
||||
dry run of this example, you will have to patch your current kernel in order to have
|
||||
<code> <span class='ectt-1000'>sys_call_table</span>
|
||||
</code> exported. In the example directory you will find a README and the patch. As you
|
||||
can imagine, such modifications are not to be taken lightly. Do not try this on
|
||||
valuable systems (ie systems that you do not own - or cannot restore easily). You will
|
||||
need to get the complete sourcecode of this guide as a tarball in order to get the
|
||||
patch and the README. Depending on your kernel version, you might even need to
|
||||
hand apply the patch.
|
||||
</code> exported.
|
||||
</p><!-- l. 1 --><p class='indent'>
|
||||
</p>
|
||||
<pre class='fancyvrb' id='fancyvrb51'><a id='x1-40044r1'></a><span class='ecrm-0500'>1</span><span id='textcolor1326'><span class='ectt-0800'>/*</span></span>
|
||||
@ -3361,13 +3356,13 @@ hand apply the patch.
|
||||
<a id='x1-40496r227'></a><span class='ecrm-0500'>227</span><span class='ectt-0800'>module_exit(syscall_end);</span>
|
||||
<a id='x1-40498r228'></a><span class='ecrm-0500'>228</span>
|
||||
<a id='x1-40500r229'></a><span class='ecrm-0500'>229</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor1568'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
||||
<!-- l. 1349 --><p class='noindent'>
|
||||
<!-- l. 1344 --><p class='noindent'>
|
||||
</p>
|
||||
<h3 class='sectionHead' id='blocking-processes-and-threads'><span class='titlemark'>11 </span> <a id='x1-4100011'></a>Blocking Processes and threads</h3>
|
||||
<!-- l. 1351 --><p class='noindent'>
|
||||
<!-- l. 1346 --><p class='noindent'>
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='sleep'><span class='titlemark'>11.1 </span> <a id='x1-4200011.1'></a>Sleep</h4>
|
||||
<!-- l. 1353 --><p class='noindent'>What do you do when somebody asks you for something you can not do right
|
||||
<!-- l. 1348 --><p class='noindent'>What do you do when somebody asks you for something you can not do right
|
||||
away? If you are a human being and you are bothered by a human being, the
|
||||
only thing you can say is: "<span class='ecti-1000'>Not right now, I’m busy. Go away!</span>". But if you
|
||||
are a kernel module and you are bothered by a process, you have another
|
||||
@ -3375,58 +3370,58 @@ possibility. You can put the process to sleep until you can service it. After al
|
||||
processes are being put to sleep by the kernel and woken up all the time (that
|
||||
is the way multiple processes appear to run on the same time on a single
|
||||
CPU).
|
||||
</p><!-- l. 1359 --><p class='indent'> This kernel module is an example of this. The file (called <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>/proc/sleep</span></span></span>) can only
|
||||
</p><!-- l. 1354 --><p class='indent'> This kernel module is an example of this. The file (called <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>/proc/sleep</span></span></span>) can only
|
||||
be opened by a single process at a time. If the file is already open, the kernel module
|
||||
calls <code> <span class='ectt-1000'>wait_event_interruptible</span>
|
||||
</code>. The easiest way to keep a file open is to open it with:
|
||||
</p><!-- l. 1 --><p class='indent'>
|
||||
</p>
|
||||
<pre class='fancyvrb' id='fancyvrb52'><a id='x1-42004r1'></a><span class='ecrm-0500'>1</span><span class='ectt-1000'>tail -f</span></pre>
|
||||
<!-- l. 1368 --><p class='indent'> This function changes the status of the task (a task is the kernel data structure
|
||||
<!-- l. 1363 --><p class='indent'> This function changes the status of the task (a task is the kernel data structure
|
||||
which holds information about a process and the system call it is in, if any) to
|
||||
<code> <span class='ectt-1000'>TASK_INTERRUPTIBLE</span>
|
||||
</code>, which means that the task will not run until it is woken up somehow, and adds it to
|
||||
WaitQ, the queue of tasks waiting to access the file. Then, the function calls the
|
||||
scheduler to context switch to a different process, one which has some use for the
|
||||
CPU.
|
||||
|
||||
|
||||
|
||||
</p><!-- l. 1372 --><p class='indent'> When a process is done with the file, it closes it, and
|
||||
</p><!-- l. 1367 --><p class='indent'> When a process is done with the file, it closes it, and
|
||||
<code> <span class='ectt-1000'>module_close</span>
|
||||
</code> is called. That function wakes up all the processes in the queue (there’s no
|
||||
mechanism to only wake up one of them). It then returns and the process which just
|
||||
|
||||
|
||||
|
||||
closed the file can continue to run. In time, the scheduler decides that that
|
||||
process has had enough and gives control of the CPU to another process.
|
||||
Eventually, one of the processes which was in the queue will be given control
|
||||
of the CPU by the scheduler. It starts at the point right after the call to
|
||||
<code> <span class='ectt-1000'>module_interruptible_sleep_on</span>
|
||||
</code>.
|
||||
</p><!-- l. 1379 --><p class='indent'> This means that the process is still in kernel mode - as far as the process
|
||||
</p><!-- l. 1374 --><p class='indent'> This means that the process is still in kernel mode - as far as the process
|
||||
is concerned, it issued the open system call and the system call has not
|
||||
returned yet. The process does not know somebody else used the CPU for
|
||||
most of the time between the moment it issued the call and the moment it
|
||||
returned.
|
||||
</p><!-- l. 1382 --><p class='indent'> It can then proceed to set a global variable to tell all the other processes that the
|
||||
</p><!-- l. 1377 --><p class='indent'> It can then proceed to set a global variable to tell all the other processes that the
|
||||
file is still open and go on with its life. When the other processes get a piece of the
|
||||
CPU, they’ll see that global variable and go back to sleep.
|
||||
</p><!-- l. 1385 --><p class='indent'> So we will use <code> <span class='ectt-1000'>tail -f</span>
|
||||
</p><!-- l. 1380 --><p class='indent'> So we will use <code> <span class='ectt-1000'>tail -f</span>
|
||||
</code> to keep the file open in the background, while trying to access it with another
|
||||
process (again in the background, so that we need not switch to a different vt). As
|
||||
soon as the first background process is killed with kill %1 , the second is woken up, is
|
||||
able to access the file and finally terminates.
|
||||
</p><!-- l. 1388 --><p class='indent'> To make our life more interesting, <code> <span class='ectt-1000'>module_close</span>
|
||||
</p><!-- l. 1383 --><p class='indent'> To make our life more interesting, <code> <span class='ectt-1000'>module_close</span>
|
||||
</code> does not have a monopoly on waking up the processes which wait to access the file.
|
||||
A signal, such as <span class='ecti-1000'>Ctrl +c </span>(<span class='ecbx-1000'>SIGINT</span>) can also wake up a process. This is because we
|
||||
used <code> <span class='ectt-1000'>module_interruptible_sleep_on</span>
|
||||
</code>. We could have used <code> <span class='ectt-1000'>module_sleep_on</span>
|
||||
</code> instead, but that would have resulted in extremely angry users whose <span class='ecti-1000'>Ctrl+c</span>’s are
|
||||
ignored.
|
||||
</p><!-- l. 1392 --><p class='indent'> In that case, we want to return with
|
||||
</p><!-- l. 1387 --><p class='indent'> In that case, we want to return with
|
||||
<code> <span class='ectt-1000'>-EINTR</span>
|
||||
</code> immediately. This is important so users can, for example, kill the process before it
|
||||
receives the file.
|
||||
</p><!-- l. 1394 --><p class='indent'> There is one more point to remember. Some times processes don’t want to sleep, they want
|
||||
</p><!-- l. 1389 --><p class='indent'> There is one more point to remember. Some times processes don’t want to sleep, they want
|
||||
either to get what they want immediately, or to be told it cannot be done. Such processes
|
||||
use the <code> <span class='ectt-1000'>O_NONBLOCK</span>
|
||||
</code> flag when opening the file. The kernel is supposed to respond by returning with the error
|
||||
@ -3462,7 +3457,7 @@ $ cat_nonblock /proc/sleep
|
||||
Last input:
|
||||
$
|
||||
</pre>
|
||||
<!-- l. 1419 --><p class='nopar'>
|
||||
<!-- l. 1414 --><p class='nopar'>
|
||||
</p><!-- l. 1 --><p class='indent'>
|
||||
</p>
|
||||
<pre class='fancyvrb' id='fancyvrb53'><a id='x1-42018r1'></a><span class='ecrm-0500'>1</span><span id='textcolor1569'><span class='ectt-0800'>/*</span></span>
|
||||
@ -3741,14 +3736,14 @@ $
|
||||
<a id='x1-42558r57'></a><span class='ecrm-0500'>57</span>
|
||||
<a id='x1-42560r58'></a><span class='ecrm-0500'>58</span><span class='ectt-0800'> </span><span id='textcolor1805'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> 0;</span>
|
||||
<a id='x1-42562r59'></a><span class='ecrm-0500'>59</span><span class='ectt-0800'>}</span></pre>
|
||||
<!-- l. 1425 --><p class='noindent'>
|
||||
<!-- l. 1420 --><p class='noindent'>
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='completions'><span class='titlemark'>11.2 </span> <a id='x1-4300011.2'></a>Completions</h4>
|
||||
<!-- l. 1427 --><p class='noindent'>Sometimes one thing should happen before another within a module having multiple threads.
|
||||
<!-- l. 1422 --><p class='noindent'>Sometimes one thing should happen before another within a module having multiple threads.
|
||||
Rather than using <code> <span class='ectt-1000'>/bin/sleep</span>
|
||||
</code> commands, the kernel has another way to do this which allows timeouts or
|
||||
interrupts to also happen.
|
||||
</p><!-- l. 1430 --><p class='indent'> In the following example two threads are started, but one needs to start before
|
||||
</p><!-- l. 1425 --><p class='indent'> In the following example two threads are started, but one needs to start before
|
||||
another.
|
||||
</p><!-- l. 1 --><p class='indent'>
|
||||
|
||||
@ -3831,31 +3826,31 @@ another.
|
||||
<a id='x1-43149r74'></a><span class='ecrm-0500'>74</span>
|
||||
<a id='x1-43151r75'></a><span class='ecrm-0500'>75</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor1857'><span class='ectt-0800'>"Completions example"</span></span><span class='ectt-0800'>);</span>
|
||||
<a id='x1-43153r76'></a><span class='ecrm-0500'>76</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor1858'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
||||
<!-- l. 1434 --><p class='indent'> The <code> <span class='ectt-1000'>machine</span>
|
||||
<!-- l. 1429 --><p class='indent'> The <code> <span class='ectt-1000'>machine</span>
|
||||
</code> structure stores the completion states for the two threads. At the exit
|
||||
point of each thread the respective completion state is updated, and
|
||||
<code> <span class='ectt-1000'>wait_for_completion</span>
|
||||
</code> is used by the flywheel thread to ensure that it does not begin prematurely.
|
||||
</p><!-- l. 1437 --><p class='indent'> So even though <code> <span class='ectt-1000'>flywheel_thread</span>
|
||||
</p><!-- l. 1432 --><p class='indent'> So even though <code> <span class='ectt-1000'>flywheel_thread</span>
|
||||
</code> is started first you should notice if you load this module and run
|
||||
<code> <span class='ectt-1000'>dmesg</span>
|
||||
</code> that turning the crank always happens first because the flywheel thread waits for it
|
||||
to complete.
|
||||
</p><!-- l. 1439 --><p class='indent'> There are other variations upon the
|
||||
</p><!-- l. 1434 --><p class='indent'> There are other variations upon the
|
||||
<code> <span class='ectt-1000'>wait_for_completion</span>
|
||||
</code> function, which include timeouts or being interrupted, but this basic mechanism is
|
||||
enough for many common situations without adding a lot of complexity.
|
||||
</p><!-- l. 1441 --><p class='noindent'>
|
||||
</p><!-- l. 1436 --><p class='noindent'>
|
||||
</p>
|
||||
<h3 class='sectionHead' id='avoiding-collisions-and-deadlocks'><span class='titlemark'>12 </span> <a id='x1-4400012'></a>Avoiding Collisions and Deadlocks</h3>
|
||||
<!-- l. 1443 --><p class='noindent'>If processes running on different CPUs or in different threads try to access the same
|
||||
<!-- l. 1438 --><p class='noindent'>If processes running on different CPUs or in different threads try to access the same
|
||||
memory, then it is possible that strange things can happen or your system can lock
|
||||
up. To avoid this, various types of mutual exclusion kernel functions are available.
|
||||
These indicate if a section of code is "locked" or "unlocked" so that simultaneous
|
||||
attempts to run it can not happen.
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='mutex'><span class='titlemark'>12.1 </span> <a id='x1-4500012.1'></a>Mutex</h4>
|
||||
<!-- l. 1448 --><p class='noindent'>You can use kernel mutexes (mutual exclusions) in much the same manner that you
|
||||
<!-- l. 1443 --><p class='noindent'>You can use kernel mutexes (mutual exclusions) in much the same manner that you
|
||||
might deploy them in userland. This may be all that is needed to avoid collisions in
|
||||
most cases.
|
||||
</p><!-- l. 1 --><p class='indent'>
|
||||
@ -3901,10 +3896,10 @@ most cases.
|
||||
<a id='x1-45078r39'></a><span class='ecrm-0500'>39</span>
|
||||
<a id='x1-45080r40'></a><span class='ecrm-0500'>40</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor1900'><span class='ectt-0800'>"Mutex example"</span></span><span class='ectt-0800'>);</span>
|
||||
<a id='x1-45082r41'></a><span class='ecrm-0500'>41</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor1901'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
||||
<!-- l. 1453 --><p class='noindent'>
|
||||
<!-- l. 1448 --><p class='noindent'>
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='spinlocks'><span class='titlemark'>12.2 </span> <a id='x1-4600012.2'></a>Spinlocks</h4>
|
||||
<!-- l. 1455 --><p class='noindent'>As the name suggests, spinlocks lock up the CPU that the code is running on,
|
||||
<!-- l. 1450 --><p class='noindent'>As the name suggests, spinlocks lock up the CPU that the code is running on,
|
||||
taking 100% of its resources. Because of this you should only use the spinlock
|
||||
|
||||
|
||||
@ -3912,7 +3907,7 @@ taking 100% of its resources. Because of this you should only use the spinlock
|
||||
mechanism around code which is likely to take no more than a few milliseconds to
|
||||
run and so will not noticeably slow anything down from the user’s point of
|
||||
view.
|
||||
</p><!-- l. 1458 --><p class='indent'> The example here is <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>"irq safe"</span></span></span> in that if interrupts happen during the lock then
|
||||
</p><!-- l. 1453 --><p class='indent'> The example here is <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>"irq safe"</span></span></span> in that if interrupts happen during the lock then
|
||||
they will not be forgotten and will activate when the unlock happens, using the
|
||||
<code> <span class='ectt-1000'>flags</span>
|
||||
</code> variable to retain their state.
|
||||
@ -3981,10 +3976,10 @@ they will not be forgotten and will activate when the unlock happens, using the
|
||||
<a id='x1-46123r61'></a><span class='ecrm-0500'>61</span>
|
||||
<a id='x1-46125r62'></a><span class='ecrm-0500'>62</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor1958'><span class='ectt-0800'>"Spinlock example"</span></span><span class='ectt-0800'>);</span>
|
||||
<a id='x1-46127r63'></a><span class='ecrm-0500'>63</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor1959'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
||||
<!-- l. 1462 --><p class='noindent'>
|
||||
<!-- l. 1457 --><p class='noindent'>
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='read-and-write-locks'><span class='titlemark'>12.3 </span> <a id='x1-4700012.3'></a>Read and write locks</h4>
|
||||
<!-- l. 1464 --><p class='noindent'>Read and write locks are specialised kinds of spinlocks so that you can exclusively
|
||||
<!-- l. 1459 --><p class='noindent'>Read and write locks are specialised kinds of spinlocks so that you can exclusively
|
||||
read from something or write to something. Like the earlier spinlocks example, the
|
||||
one below shows an "irq safe" situation in which if other functions were triggered
|
||||
from irqs which might also read and write to whatever you are concerned with
|
||||
@ -4049,14 +4044,14 @@ module.
|
||||
<a id='x1-47106r53'></a><span class='ecrm-0500'>53</span>
|
||||
<a id='x1-47108r54'></a><span class='ecrm-0500'>54</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor2007'><span class='ectt-0800'>"Read/Write locks example"</span></span><span class='ectt-0800'>);</span>
|
||||
<a id='x1-47110r55'></a><span class='ecrm-0500'>55</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor2008'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
||||
<!-- l. 1470 --><p class='indent'> Of course, if you know for sure that there are no functions triggered by irqs
|
||||
<!-- l. 1465 --><p class='indent'> Of course, if you know for sure that there are no functions triggered by irqs
|
||||
which could possibly interfere with your logic then you can use the simpler
|
||||
<code> <span class='ectt-1000'>read_lock(&myrwlock)</span>
|
||||
</code> and <code> <span class='ectt-1000'>read_unlock(&myrwlock)</span>
|
||||
</code> or the corresponding write functions.
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='atomic-operations'><span class='titlemark'>12.4 </span> <a id='x1-4800012.4'></a>Atomic operations</h4>
|
||||
<!-- l. 1473 --><p class='noindent'>If you are doing simple arithmetic: adding, subtracting or bitwise operations, then
|
||||
<!-- l. 1468 --><p class='noindent'>If you are doing simple arithmetic: adding, subtracting or bitwise operations, then
|
||||
there is another way in the multi-CPU and multi-hyperthreaded world to stop other
|
||||
parts of the system from messing with your mojo. By using atomic operations you
|
||||
can be confident that your addition, subtraction or bit flip did actually happen
|
||||
@ -4141,7 +4136,7 @@ below.
|
||||
|
||||
|
||||
|
||||
<!-- l. 1479 --><p class='indent'> Before the C11 standard adopts the built-in atomic types, the kernel already
|
||||
<!-- l. 1474 --><p class='indent'> Before the C11 standard adopts the built-in atomic types, the kernel already
|
||||
provided a small set of atomic types by using a bunch of tricky architecture-specific
|
||||
codes. Implementing the atomic types by C11 atomics may allow the kernel to throw
|
||||
away the architecture-specific codes and letting the kernel code be more friendly to
|
||||
@ -4154,21 +4149,21 @@ For further details, see: </p>
|
||||
<li class='itemize'><a href='https://lwn.net/Articles/691128/'>Time to move to C11 atomics?</a>
|
||||
</li>
|
||||
<li class='itemize'><a href='https://lwn.net/Articles/698315/'>Atomic usage patterns in the kernel</a></li></ul>
|
||||
<!-- l. 1490 --><p class='noindent'>
|
||||
<!-- l. 1485 --><p class='noindent'>
|
||||
</p>
|
||||
<h3 class='sectionHead' id='replacing-print-macros'><span class='titlemark'>13 </span> <a id='x1-4900013'></a>Replacing Print Macros</h3>
|
||||
<!-- l. 1492 --><p class='noindent'>
|
||||
<!-- l. 1487 --><p class='noindent'>
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='replacement'><span class='titlemark'>13.1 </span> <a id='x1-5000013.1'></a>Replacement</h4>
|
||||
<!-- l. 1494 --><p class='noindent'>In Section <a href='#x1-80042'>2<!-- tex4ht:ref: sec:using_x --></a>, I said that X Window System and kernel module programming do not
|
||||
<!-- l. 1489 --><p class='noindent'>In Section <a href='#x1-80042'>2<!-- tex4ht:ref: sec:using_x --></a>, I said that X Window System and kernel module programming do not
|
||||
mix. That is true for developing kernel modules. But in actual use, you want to be
|
||||
able to send messages to whichever tty the command to load the module came
|
||||
from.
|
||||
</p><!-- l. 1498 --><p class='indent'> "tty" is an abbreviation of <span class='ecti-1000'>teletype</span>: originally a combination keyboard-printer
|
||||
</p><!-- l. 1493 --><p class='indent'> "tty" is an abbreviation of <span class='ecti-1000'>teletype</span>: originally a combination keyboard-printer
|
||||
used to communicate with a Unix system, and today an abstraction for the text
|
||||
stream used for a Unix program, whether it is a physical terminal, an xterm on an X
|
||||
display, a network connection used with ssh, etc.
|
||||
</p><!-- l. 1500 --><p class='indent'> The way this is done is by using current, a pointer to the currently running task,
|
||||
</p><!-- l. 1495 --><p class='indent'> The way this is done is by using current, a pointer to the currently running task,
|
||||
to get the current task’s tty structure. Then, we look inside that tty structure to find
|
||||
a pointer to a string write function, which we use to write a string to the
|
||||
tty.
|
||||
@ -4251,16 +4246,16 @@ tty.
|
||||
|
||||
|
||||
|
||||
<!-- l. 1505 --><p class='noindent'>
|
||||
<!-- l. 1500 --><p class='noindent'>
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='flashing-keyboard-leds'><span class='titlemark'>13.2 </span> <a id='x1-5100013.2'></a>Flashing keyboard LEDs</h4>
|
||||
<!-- l. 1507 --><p class='noindent'>In certain conditions, you may desire a simpler and more direct way to communicate
|
||||
<!-- l. 1502 --><p class='noindent'>In certain conditions, you may desire a simpler and more direct way to communicate
|
||||
to the external world. Flashing keyboard LEDs can be such a solution: It is an
|
||||
immediate way to attract attention or to display a status condition. Keyboard LEDs
|
||||
are present on every hardware, they are always visible, they do not need any setup,
|
||||
and their use is rather simple and non-intrusive, compared to writing to a tty or a
|
||||
file.
|
||||
</p><!-- l. 1511 --><p class='indent'> From v4.14 to v4.15, the timer API made a series of changes
|
||||
</p><!-- l. 1506 --><p class='indent'> From v4.14 to v4.15, the timer API made a series of changes
|
||||
to improve memory safety. A buffer overflow in the area of a
|
||||
<code> <span class='ectt-1000'>timer_list</span>
|
||||
</code> structure may be able to overwrite the
|
||||
@ -4283,7 +4278,7 @@ to use a unique prototype to separate from the cluster that takes an
|
||||
<code> <span class='ectt-1000'>container_of</span>
|
||||
</code> macro instead of the <code> <span id='textcolor2142'><span class='ectt-1000'>unsigned</span></span><span class='ectt-1000'> </span><span id='textcolor2143'><span class='ectt-1000'>long</span></span>
|
||||
</code> value.
|
||||
</p><!-- l. 1519 --><p class='indent'> Before Linux v4.14, <code> <span class='ectt-1000'>setup_timer</span>
|
||||
</p><!-- l. 1514 --><p class='indent'> Before Linux v4.14, <code> <span class='ectt-1000'>setup_timer</span>
|
||||
</code> was used to initialize the timer and the
|
||||
<code> <span class='ectt-1000'>timer_list</span>
|
||||
</code> structure looked like:
|
||||
@ -4298,7 +4293,7 @@ to use a unique prototype to separate from the cluster that takes an
|
||||
<a id='x1-51039r8'></a><span class='ecrm-0500'>8</span>
|
||||
<a id='x1-51041r9'></a><span class='ecrm-0500'>9</span><span id='textcolor2153'><span class='ectt-0800'>void</span></span><span class='ectt-0800'> setup_timer(</span><span id='textcolor2154'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> timer_list *timer, </span><span id='textcolor2155'><span class='ectt-0800'>void</span></span><span class='ectt-0800'> (*callback)(</span><span id='textcolor2156'><span class='ectt-0800'>unsigned</span></span><span class='ectt-0800'> </span><span id='textcolor2157'><span class='ectt-0800'>long</span></span><span class='ectt-0800'>),</span>
|
||||
<a id='x1-51043r10'></a><span class='ecrm-0500'>10</span><span class='ectt-0800'> </span><span id='textcolor2158'><span class='ectt-0800'>unsigned</span></span><span class='ectt-0800'> </span><span id='textcolor2159'><span class='ectt-0800'>long</span></span><span class='ectt-0800'> data);</span></pre>
|
||||
<!-- l. 1533 --><p class='indent'> Since Linux v4.14, <code> <span class='ectt-1000'>timer_setup</span>
|
||||
<!-- l. 1528 --><p class='indent'> Since Linux v4.14, <code> <span class='ectt-1000'>timer_setup</span>
|
||||
</code> is adopted and the kernel step by step converting to
|
||||
<code> <span class='ectt-1000'>timer_setup</span>
|
||||
</code> from <code> <span class='ectt-1000'>setup_timer</span>
|
||||
@ -4312,7 +4307,7 @@ Moreover, the <code> <span class='ectt-1000'>timer_setup</span>
|
||||
</p>
|
||||
<pre class='fancyvrb' id='fancyvrb62'><a id='x1-51052r1'></a><span class='ecrm-0500'>1</span><span id='textcolor2160'><span class='ectt-0800'>void</span></span><span class='ectt-0800'> timer_setup(</span><span id='textcolor2161'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> timer_list *timer,</span>
|
||||
<a id='x1-51054r2'></a><span class='ecrm-0500'>2</span><span class='ectt-0800'> </span><span id='textcolor2162'><span class='ectt-0800'>void</span></span><span class='ectt-0800'> (*callback)(</span><span id='textcolor2163'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> timer_list *), </span><span id='textcolor2164'><span class='ectt-0800'>unsigned</span></span><span class='ectt-0800'> </span><span id='textcolor2165'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> flags);</span></pre>
|
||||
<!-- l. 1541 --><p class='indent'> The <code> <span class='ectt-1000'>setup_timer</span>
|
||||
<!-- l. 1536 --><p class='indent'> The <code> <span class='ectt-1000'>setup_timer</span>
|
||||
</code> was then removed since v4.15. As a result, the
|
||||
<code> <span class='ectt-1000'>timer_list</span>
|
||||
</code> structure had changed to the following.
|
||||
@ -4323,7 +4318,7 @@ Moreover, the <code> <span class='ectt-1000'>timer_setup</span>
|
||||
<a id='x1-51070r4'></a><span class='ecrm-0500'>4</span><span class='ectt-0800'> u32 flags;</span>
|
||||
<a id='x1-51072r5'></a><span class='ecrm-0500'>5</span><span class='ectt-0800'> </span><span id='textcolor2171'><span class='ectt-0800'>/* ... */</span></span>
|
||||
<a id='x1-51074r6'></a><span class='ecrm-0500'>6</span><span class='ectt-0800'>};</span></pre>
|
||||
<!-- l. 1552 --><p class='indent'> The following source code illustrates a minimal kernel module which, when
|
||||
<!-- l. 1547 --><p class='indent'> The following source code illustrates a minimal kernel module which, when
|
||||
loaded, starts blinking the keyboard LEDs until it is unloaded.
|
||||
</p><!-- l. 1 --><p class='indent'>
|
||||
</p>
|
||||
@ -4412,7 +4407,7 @@ loaded, starts blinking the keyboard LEDs until it is unloaded.
|
||||
<a id='x1-51240r83'></a><span class='ecrm-0500'>83</span><span class='ectt-0800'>module_exit(kbleds_cleanup);</span>
|
||||
<a id='x1-51242r84'></a><span class='ecrm-0500'>84</span>
|
||||
<a id='x1-51244r85'></a><span class='ecrm-0500'>85</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor2249'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
||||
<!-- l. 1556 --><p class='indent'> If none of the examples in this chapter fit your debugging needs,
|
||||
<!-- l. 1551 --><p class='indent'> If none of the examples in this chapter fit your debugging needs,
|
||||
there might yet be some other tricks to try. Ever wondered what
|
||||
<code> <span class='ectt-1000'>CONFIG_LL_DEBUG</span>
|
||||
</code> in <code> <span class='ectt-1000'>make menuconfig</span>
|
||||
@ -4423,25 +4418,25 @@ everything what your code does over a serial line. If you find yourself porting
|
||||
kernel to some new and former unsupported architecture, this is usually amongst the
|
||||
first things that should be implemented. Logging over a netconsole might also be
|
||||
worth a try.
|
||||
</p><!-- l. 1563 --><p class='indent'> While you have seen lots of stuff that can be used to aid debugging here, there are
|
||||
</p><!-- l. 1558 --><p class='indent'> While you have seen lots of stuff that can be used to aid debugging here, there are
|
||||
some things to be aware of. Debugging is almost always intrusive. Adding debug code
|
||||
can change the situation enough to make the bug seem to dissappear. Thus you
|
||||
should try to keep debug code to a minimum and make sure it does not show up in
|
||||
production code.
|
||||
</p><!-- l. 1567 --><p class='noindent'>
|
||||
</p><!-- l. 1562 --><p class='noindent'>
|
||||
</p>
|
||||
<h3 class='sectionHead' id='scheduling-tasks'><span class='titlemark'>14 </span> <a id='x1-5200014'></a>Scheduling Tasks</h3>
|
||||
<!-- l. 1569 --><p class='noindent'>There are two main ways of running tasks: tasklets and work queues. Tasklets are a
|
||||
<!-- l. 1564 --><p class='noindent'>There are two main ways of running tasks: tasklets and work queues. Tasklets are a
|
||||
quick and easy way of scheduling a single function to be run. For example, when
|
||||
triggered from an interrupt, whereas work queues are more complicated but also
|
||||
better suited to running multiple things in a sequence.
|
||||
|
||||
|
||||
|
||||
</p><!-- l. 1573 --><p class='noindent'>
|
||||
</p><!-- l. 1568 --><p class='noindent'>
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='tasklets'><span class='titlemark'>14.1 </span> <a id='x1-5300014.1'></a>Tasklets</h4>
|
||||
<!-- l. 1575 --><p class='noindent'>Here is an example tasklet module. The
|
||||
<!-- l. 1570 --><p class='noindent'>Here is an example tasklet module. The
|
||||
<code> <span class='ectt-1000'>tasklet_fn</span>
|
||||
</code> function runs for a few seconds and in the mean time execution of the
|
||||
<code> <span class='ectt-1000'>example_tasklet_init</span>
|
||||
@ -4492,7 +4487,7 @@ better suited to running multiple things in a sequence.
|
||||
<a id='x1-53086r42'></a><span class='ecrm-0500'>42</span>
|
||||
<a id='x1-53088r43'></a><span class='ecrm-0500'>43</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor2294'><span class='ectt-0800'>"Tasklet example"</span></span><span class='ectt-0800'>);</span>
|
||||
<a id='x1-53090r44'></a><span class='ecrm-0500'>44</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor2295'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
||||
<!-- l. 1580 --><p class='indent'> So with this example loaded <code> <span class='ectt-1000'>dmesg</span>
|
||||
<!-- l. 1575 --><p class='indent'> So with this example loaded <code> <span class='ectt-1000'>dmesg</span>
|
||||
</code> should show:
|
||||
|
||||
|
||||
@ -4504,23 +4499,23 @@ Example tasklet starts
|
||||
Example tasklet init continues...
|
||||
Example tasklet ends
|
||||
</pre>
|
||||
<!-- l. 1587 --><p class='nopar'>Although tasklet is easy to use, it comes with several defators, and developers are
|
||||
<!-- l. 1582 --><p class='nopar'>Although tasklet is easy to use, it comes with several defators, and developers are
|
||||
discussing about getting rid of tasklet in linux kernel. The tasklet callback
|
||||
runs in atomic context, inside a software interrupt, meaning that it cannot
|
||||
sleep or access user-space data, so not all work can be done in a tasklet
|
||||
handler. Also, the kernel only allows one instance of any given tasklet to be
|
||||
running at any given time; multiple different tasklet callbacks can run in
|
||||
parallel.
|
||||
</p><!-- l. 1592 --><p class='indent'> In recent kernels, tasklets can be replaced by workqueues, timers, or threaded
|
||||
</p><!-- l. 1587 --><p class='indent'> In recent kernels, tasklets can be replaced by workqueues, timers, or threaded
|
||||
interrupts.<span class='footnote-mark'><a href='#fn1x0' id='fn1x0-bk'><sup class='textsuperscript'>1</sup></a></span><a id='x1-53092f1'></a>
|
||||
While the removal of tasklets remains a longer-term goal, the current kernel contains more
|
||||
than a hundred uses of tasklets. Now developers are proceeding with the API changes and
|
||||
the macro <code> <span class='ectt-1000'>DECLARE_TASKLET_OLD</span>
|
||||
</code> exists for compatibility. For further information, see <a class='url' href='https://lwn.net/Articles/830964/'><span class='ectt-1000'>https://lwn.net/Articles/830964/</span></a>.
|
||||
</p><!-- l. 1598 --><p class='noindent'>
|
||||
</p><!-- l. 1593 --><p class='noindent'>
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='work-queues'><span class='titlemark'>14.2 </span> <a id='x1-5400014.2'></a>Work queues</h4>
|
||||
<!-- l. 1600 --><p class='noindent'>To add a task to the scheduler we can use a workqueue. The kernel then uses the
|
||||
<!-- l. 1595 --><p class='noindent'>To add a task to the scheduler we can use a workqueue. The kernel then uses the
|
||||
Completely Fair Scheduler (CFS) to execute work within the queue.
|
||||
</p><!-- l. 1 --><p class='indent'>
|
||||
</p>
|
||||
@ -4557,36 +4552,36 @@ Completely Fair Scheduler (CFS) to execute work within the queue.
|
||||
<a id='x1-54062r31'></a><span class='ecrm-0500'>31</span>
|
||||
<a id='x1-54064r32'></a><span class='ecrm-0500'>32</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor2323'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span>
|
||||
<a id='x1-54066r33'></a><span class='ecrm-0500'>33</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor2324'><span class='ectt-0800'>"Workqueue example"</span></span><span class='ectt-0800'>);</span></pre>
|
||||
<!-- l. 1605 --><p class='noindent'>
|
||||
<!-- l. 1600 --><p class='noindent'>
|
||||
</p>
|
||||
<h3 class='sectionHead' id='interrupt-handlers'><span class='titlemark'>15 </span> <a id='x1-5500015'></a>Interrupt Handlers</h3>
|
||||
<!-- l. 1607 --><p class='noindent'>
|
||||
<!-- l. 1602 --><p class='noindent'>
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
<h4 class='subsectionHead' id='interrupt-handlers1'><span class='titlemark'>15.1 </span> <a id='x1-5600015.1'></a>Interrupt Handlers</h4>
|
||||
<!-- l. 1609 --><p class='noindent'>Except for the last chapter, everything we did in the kernel so far we have done as a
|
||||
<!-- l. 1604 --><p class='noindent'>Except for the last chapter, everything we did in the kernel so far we have done as a
|
||||
response to a process asking for it, either by dealing with a special file, sending an
|
||||
<code> <span class='ectt-1000'>ioctl()</span>
|
||||
</code>, or issuing a system call. But the job of the kernel is not just to respond to process
|
||||
requests. Another job, which is every bit as important, is to speak to the hardware
|
||||
connected to the machine.
|
||||
</p><!-- l. 1613 --><p class='indent'> There are two types of interaction between the CPU and the rest of the
|
||||
</p><!-- l. 1608 --><p class='indent'> There are two types of interaction between the CPU and the rest of the
|
||||
computer’s hardware. The first type is when the CPU gives orders to the hardware,
|
||||
the order is when the hardware needs to tell the CPU something. The second, called
|
||||
interrupts, is much harder to implement because it has to be dealt with when
|
||||
convenient for the hardware, not the CPU. Hardware devices typically have a very
|
||||
small amount of RAM, and if you do not read their information when available, it is
|
||||
lost.
|
||||
</p><!-- l. 1618 --><p class='indent'> Under Linux, hardware interrupts are called IRQ’s (Interrupt ReQuests). There
|
||||
</p><!-- l. 1613 --><p class='indent'> Under Linux, hardware interrupts are called IRQ’s (Interrupt ReQuests). There
|
||||
are two types of IRQ’s, short and long. A short IRQ is one which is expected to take
|
||||
a very short period of time, during which the rest of the machine will be blocked and
|
||||
no other interrupts will be handled. A long IRQ is one which can take longer, and
|
||||
during which other interrupts may occur (but not interrupts from the same
|
||||
device). If at all possible, it is better to declare an interrupt handler to be
|
||||
long.
|
||||
</p><!-- l. 1624 --><p class='indent'> When the CPU receives an interrupt, it stops whatever it is doing (unless it is
|
||||
</p><!-- l. 1619 --><p class='indent'> When the CPU receives an interrupt, it stops whatever it is doing (unless it is
|
||||
processing a more important interrupt, in which case it will deal with this one only
|
||||
when the more important one is done), saves certain parameters on the stack and
|
||||
calls the interrupt handler. This means that certain things are not allowed in the
|
||||
@ -4598,10 +4593,10 @@ heavy work deferred from an interrupt handler. Historically, BH (Linux
|
||||
naming for <span class='ecti-1000'>Bottom Halves</span>) statistically book-keeps the deferred functions.
|
||||
<span class='ecbx-1000'>Softirq </span>and its higher level abstraction, <span class='ecbx-1000'>Tasklet</span>, replace BH since Linux
|
||||
2.3.
|
||||
</p><!-- l. 1634 --><p class='indent'> The way to implement this is to call
|
||||
</p><!-- l. 1629 --><p class='indent'> The way to implement this is to call
|
||||
<code> <span class='ectt-1000'>request_irq()</span>
|
||||
</code> to get your interrupt handler called when the relevant IRQ is received.
|
||||
</p><!-- l. 1636 --><p class='indent'> In practice IRQ handling can be a bit more complex. Hardware is often
|
||||
</p><!-- l. 1631 --><p class='indent'> In practice IRQ handling can be a bit more complex. Hardware is often
|
||||
designed in a way that chains two interrupt controllers, so that all the IRQs
|
||||
from interrupt controller B are cascaded to a certain IRQ from interrupt
|
||||
controller A. Of course, that requires that the kernel finds out which IRQ it
|
||||
@ -4618,7 +4613,7 @@ need to solve another truckload of problems. It is not enough to know if a
|
||||
certain IRQs has happened, it’s also important to know what CPU(s) it was
|
||||
for. People still interested in more details, might want to refer to "APIC"
|
||||
now.
|
||||
</p><!-- l. 1645 --><p class='indent'> This function receives the IRQ number, the name of the function,
|
||||
</p><!-- l. 1640 --><p class='indent'> This function receives the IRQ number, the name of the function,
|
||||
flags, a name for <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>/proc/interrupts</span></span></span> and a parameter to be passed to the
|
||||
interrupt handler. Usually there is a certain number of IRQs available.
|
||||
How many IRQs there are is hardware-dependent. The flags can include
|
||||
@ -4628,16 +4623,16 @@ How many IRQs there are is hardware-dependent. The flags can include
|
||||
<code> <span class='ectt-1000'>SA_INTERRUPT</span>
|
||||
</code> to indicate this is a fast interrupt. This function will only succeed if there is not
|
||||
already a handler on this IRQ, or if you are both willing to share.
|
||||
</p><!-- l. 1651 --><p class='noindent'>
|
||||
</p><!-- l. 1646 --><p class='noindent'>
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='detecting-button-presses'><span class='titlemark'>15.2 </span> <a id='x1-5700015.2'></a>Detecting button presses</h4>
|
||||
<!-- l. 1653 --><p class='noindent'>Many popular single board computers, such as Raspberry Pi or Beagleboards, have a
|
||||
<!-- l. 1648 --><p class='noindent'>Many popular single board computers, such as Raspberry Pi or Beagleboards, have a
|
||||
bunch of GPIO pins. Attaching buttons to those and then having a button press do
|
||||
something is a classic case in which you might need to use interrupts, so that instead
|
||||
of having the CPU waste time and battery power polling for a change in input state,
|
||||
it is better for the input to trigger the CPU to then run a particular handling
|
||||
function.
|
||||
</p><!-- l. 1657 --><p class='indent'> Here is an example where buttons are connected to GPIO numbers 17 and 18 and
|
||||
</p><!-- l. 1652 --><p class='indent'> Here is an example where buttons are connected to GPIO numbers 17 and 18 and
|
||||
an LED is connected to GPIO 4. You can change those numbers to whatever is
|
||||
appropriate for your board.
|
||||
</p><!-- l. 1 --><p class='indent'>
|
||||
@ -4786,14 +4781,14 @@ appropriate for your board.
|
||||
<a id='x1-57284r142'></a><span class='ecrm-0500'>142</span>
|
||||
<a id='x1-57286r143'></a><span class='ecrm-0500'>143</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor2431'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span>
|
||||
<a id='x1-57288r144'></a><span class='ecrm-0500'>144</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor2432'><span class='ectt-0800'>"Handle some GPIO interrupts"</span></span><span class='ectt-0800'>);</span></pre>
|
||||
<!-- l. 1662 --><p class='noindent'>
|
||||
<!-- l. 1657 --><p class='noindent'>
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='bottom-half'><span class='titlemark'>15.3 </span> <a id='x1-5800015.3'></a>Bottom Half</h4>
|
||||
<!-- l. 1664 --><p class='noindent'>Suppose you want to do a bunch of stuff inside of an interrupt routine. A common
|
||||
<!-- l. 1659 --><p class='noindent'>Suppose you want to do a bunch of stuff inside of an interrupt routine. A common
|
||||
way to do that without rendering the interrupt unavailable for a significant duration
|
||||
is to combine it with a tasklet. This pushes the bulk of the work off into the
|
||||
scheduler.
|
||||
</p><!-- l. 1668 --><p class='indent'> The example below modifies the previous example to also run an additional task
|
||||
</p><!-- l. 1663 --><p class='indent'> The example below modifies the previous example to also run an additional task
|
||||
when an interrupt is triggered.
|
||||
</p><!-- l. 1 --><p class='indent'>
|
||||
|
||||
@ -4967,19 +4962,19 @@ when an interrupt is triggered.
|
||||
<a id='x1-58330r165'></a><span class='ecrm-0500'>165</span>
|
||||
<a id='x1-58332r166'></a><span class='ecrm-0500'>166</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor2560'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span>
|
||||
<a id='x1-58334r167'></a><span class='ecrm-0500'>167</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor2561'><span class='ectt-0800'>"Interrupt with top and bottom half"</span></span><span class='ectt-0800'>);</span></pre>
|
||||
<!-- l. 1672 --><p class='noindent'>
|
||||
<!-- l. 1667 --><p class='noindent'>
|
||||
</p>
|
||||
<h3 class='sectionHead' id='crypto'><span class='titlemark'>16 </span> <a id='x1-5900016'></a>Crypto</h3>
|
||||
<!-- l. 1674 --><p class='noindent'>At the dawn of the internet, everybody trusted everybody completely…but that did
|
||||
<!-- l. 1669 --><p class='noindent'>At the dawn of the internet, everybody trusted everybody completely…but that did
|
||||
not work out so well. When this guide was originally written, it was a more innocent
|
||||
era in which almost nobody actually gave a damn about crypto - least of all kernel
|
||||
developers. That is certainly no longer the case now. To handle crypto stuff, the
|
||||
kernel has its own API enabling common methods of encryption, decryption and your
|
||||
favourite hash functions.
|
||||
</p><!-- l. 1679 --><p class='noindent'>
|
||||
</p><!-- l. 1674 --><p class='noindent'>
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='hash-functions'><span class='titlemark'>16.1 </span> <a id='x1-6000016.1'></a>Hash functions</h4>
|
||||
<!-- l. 1682 --><p class='noindent'>Calculating and checking the hashes of things is a common operation. Here is a
|
||||
<!-- l. 1677 --><p class='noindent'>Calculating and checking the hashes of things is a common operation. Here is a
|
||||
demonstration of how to calculate a sha256 hash within a kernel module.
|
||||
</p><!-- l. 1 --><p class='indent'>
|
||||
</p>
|
||||
@ -5047,20 +5042,20 @@ demonstration of how to calculate a sha256 hash within a kernel module.
|
||||
<a id='x1-60124r62'></a><span class='ecrm-0500'>62</span>
|
||||
<a id='x1-60126r63'></a><span class='ecrm-0500'>63</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor2613'><span class='ectt-0800'>"sha256 hash test"</span></span><span class='ectt-0800'>);</span>
|
||||
<a id='x1-60128r64'></a><span class='ecrm-0500'>64</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor2614'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
||||
<!-- l. 1687 --><p class='indent'> Install the module:
|
||||
<!-- l. 1682 --><p class='indent'> Install the module:
|
||||
</p><!-- l. 1 --><p class='indent'>
|
||||
</p>
|
||||
<pre class='fancyvrb' id='fancyvrb70'><a id='x1-60132r1'></a><span class='ecrm-0500'>1</span><span class='ectt-1000'>sudo insmod cryptosha256.ko</span>
|
||||
<a id='x1-60134r2'></a><span class='ecrm-0500'>2</span><span class='ectt-1000'>sudo dmesg</span></pre>
|
||||
<!-- l. 1694 --><p class='indent'> And you should see that the hash was calculated for the test string.
|
||||
</p><!-- l. 1696 --><p class='indent'> Finally, remove the test module:
|
||||
<!-- l. 1689 --><p class='indent'> And you should see that the hash was calculated for the test string.
|
||||
</p><!-- l. 1691 --><p class='indent'> Finally, remove the test module:
|
||||
</p><!-- l. 1 --><p class='indent'>
|
||||
</p>
|
||||
<pre class='fancyvrb' id='fancyvrb71'><a id='x1-60137r1'></a><span class='ecrm-0500'>1</span><span class='ectt-1000'>sudo rmmod cryptosha256</span></pre>
|
||||
<!-- l. 1702 --><p class='noindent'>
|
||||
<!-- l. 1697 --><p class='noindent'>
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='symmetric-key-encryption'><span class='titlemark'>16.2 </span> <a id='x1-6100016.2'></a>Symmetric key encryption</h4>
|
||||
<!-- l. 1704 --><p class='noindent'>Here is an example of symmetrically encrypting a string using the AES algorithm
|
||||
<!-- l. 1699 --><p class='noindent'>Here is an example of symmetrically encrypting a string using the AES algorithm
|
||||
and a password.
|
||||
</p><!-- l. 1 --><p class='indent'>
|
||||
|
||||
@ -5265,10 +5260,10 @@ and a password.
|
||||
<a id='x1-61392r196'></a><span class='ecrm-0500'>196</span>
|
||||
<a id='x1-61394r197'></a><span class='ecrm-0500'>197</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor2766'><span class='ectt-0800'>"Symmetric key encryption example"</span></span><span class='ectt-0800'>);</span>
|
||||
<a id='x1-61396r198'></a><span class='ecrm-0500'>198</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor2767'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
||||
<!-- l. 1708 --><p class='noindent'>
|
||||
<!-- l. 1703 --><p class='noindent'>
|
||||
</p>
|
||||
<h3 class='sectionHead' id='standardizing-the-interfaces-the-device-model'><span class='titlemark'>17 </span> <a id='x1-6200017'></a>Standardizing the interfaces: The Device Model</h3>
|
||||
<!-- l. 1710 --><p class='noindent'>Up to this point we have seen all kinds of modules doing all kinds of things, but there
|
||||
<!-- l. 1705 --><p class='noindent'>Up to this point we have seen all kinds of modules doing all kinds of things, but there
|
||||
was no consistency in their interfaces with the rest of the kernel. To impose some
|
||||
consistency such that there is at minimum a standardized way to start, suspend and
|
||||
resume a device a device model was added. An example is shown below, and you can
|
||||
@ -5375,13 +5370,13 @@ functions.
|
||||
<a id='x1-62194r97'></a><span class='ecrm-0500'>97</span>
|
||||
<a id='x1-62196r98'></a><span class='ecrm-0500'>98</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor2842'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span>
|
||||
<a id='x1-62198r99'></a><span class='ecrm-0500'>99</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor2843'><span class='ectt-0800'>"Linux Device Model example"</span></span><span class='ectt-0800'>);</span></pre>
|
||||
<!-- l. 1716 --><p class='noindent'>
|
||||
<!-- l. 1711 --><p class='noindent'>
|
||||
</p>
|
||||
<h3 class='sectionHead' id='optimizations'><span class='titlemark'>18 </span> <a id='x1-6300018'></a>Optimizations</h3>
|
||||
<!-- l. 1718 --><p class='noindent'>
|
||||
<!-- l. 1713 --><p class='noindent'>
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='likely-and-unlikely-conditions'><span class='titlemark'>18.1 </span> <a id='x1-6400018.1'></a>Likely and Unlikely conditions</h4>
|
||||
<!-- l. 1720 --><p class='noindent'>Sometimes you might want your code to run as quickly as possible,
|
||||
<!-- l. 1715 --><p class='noindent'>Sometimes you might want your code to run as quickly as possible,
|
||||
especially if it is handling an interrupt or doing something which might
|
||||
cause noticeable latency. If your code contains boolean conditions and if
|
||||
you know that the conditions are almost always likely to evaluate as either
|
||||
@ -5403,43 +5398,43 @@ to succeed.
|
||||
|
||||
|
||||
|
||||
<!-- l. 1734 --><p class='indent'> When the <code> <span class='ectt-1000'>unlikely</span>
|
||||
<!-- l. 1729 --><p class='indent'> When the <code> <span class='ectt-1000'>unlikely</span>
|
||||
</code> macro is used, the compiler alters its machine instruction output, so that it
|
||||
continues along the false branch and only jumps if the condition is true. That
|
||||
avoids flushing the processor pipeline. The opposite happens if you use the
|
||||
<code> <span class='ectt-1000'>likely</span>
|
||||
</code> macro.
|
||||
</p><!-- l. 1738 --><p class='noindent'>
|
||||
</p><!-- l. 1733 --><p class='noindent'>
|
||||
</p>
|
||||
<h3 class='sectionHead' id='common-pitfalls'><span class='titlemark'>19 </span> <a id='x1-6500019'></a>Common Pitfalls</h3>
|
||||
<!-- l. 1741 --><p class='noindent'>
|
||||
<!-- l. 1736 --><p class='noindent'>
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='using-standard-libraries'><span class='titlemark'>19.1 </span> <a id='x1-6600019.1'></a>Using standard libraries</h4>
|
||||
<!-- l. 1743 --><p class='noindent'>You can not do that. In a kernel module, you can only use kernel functions which are
|
||||
<!-- l. 1738 --><p class='noindent'>You can not do that. In a kernel module, you can only use kernel functions which are
|
||||
the functions you can see in <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>/proc/kallsyms</span></span></span>.
|
||||
</p><!-- l. 1746 --><p class='noindent'>
|
||||
</p><!-- l. 1741 --><p class='noindent'>
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='disabling-interrupts'><span class='titlemark'>19.2 </span> <a id='x1-6700019.2'></a>Disabling interrupts</h4>
|
||||
<!-- l. 1748 --><p class='noindent'>You might need to do this for a short time and that is OK, but if you do not enable
|
||||
<!-- l. 1743 --><p class='noindent'>You might need to do this for a short time and that is OK, but if you do not enable
|
||||
them afterwards, your system will be stuck and you will have to power it
|
||||
off.
|
||||
</p><!-- l. 1750 --><p class='noindent'>
|
||||
</p><!-- l. 1745 --><p class='noindent'>
|
||||
</p>
|
||||
<h3 class='sectionHead' id='where-to-go-from-here'><span class='titlemark'>20 </span> <a id='x1-6800020'></a>Where To Go From Here?</h3>
|
||||
<!-- l. 1752 --><p class='noindent'>For people seriously interested in kernel programming, I recommend <a href='https://kernelnewbies.org'>kernelnewbies.org</a>
|
||||
<!-- l. 1747 --><p class='noindent'>For people seriously interested in kernel programming, I recommend <a href='https://kernelnewbies.org'>kernelnewbies.org</a>
|
||||
and the <a href='https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/Documentation'>Documentation</a> subdirectory within the kernel source code which is not
|
||||
always easy to understand but can be a starting point for further investigation. Also,
|
||||
as Linus Torvalds said, the best way to learn the kernel is to read the source code
|
||||
yourself.
|
||||
</p><!-- l. 1755 --><p class='indent'> If you would like to contribute to this guide or notice anything glaringly wrong,
|
||||
</p><!-- l. 1750 --><p class='indent'> If you would like to contribute to this guide or notice anything glaringly wrong,
|
||||
please create an issue at <a class='url' href='https://github.com/sysprog21/lkmpg'><span class='ectt-1000'>https://github.com/sysprog21/lkmpg</span></a>. Your pull requests
|
||||
will be appreciated.
|
||||
</p><!-- l. 1758 --><p class='indent'> Happy hacking!
|
||||
</p><!-- l. 1753 --><p class='indent'> Happy hacking!
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
<div class='footnotes'><!-- l. 1593 --><p class='indent'> <span class='footnote-mark'><a href='#fn1x0-bk' id='fn1x0'><sup class='textsuperscript'>1</sup></a></span><span class='ecrm-0800'>The goal of threaded interrupts is to push more of the work to separate threads, so that the
|
||||
<div class='footnotes'><!-- l. 1588 --><p class='indent'> <span class='footnote-mark'><a href='#fn1x0-bk' id='fn1x0'><sup class='textsuperscript'>1</sup></a></span><span class='ecrm-0800'>The goal of threaded interrupts is to push more of the work to separate threads, so that the
|
||||
</span><span class='ecrm-0800'>minimum needed for acknowledging an interrupt is reduced, and therefore the time spent handling
|
||||
</span><span class='ecrm-0800'>the interrupt (where it can’t handle any other interrupts at the same time) is reduced. See</span>
|
||||
<a class='url' href='https://lwn.net/Articles/302043/'><span class='ectt-0800'>https://lwn.net/Articles/302043/</span></a><span class='ecrm-0800'>.</span></p> </div>
|
||||
|
Loading…
x
Reference in New Issue
Block a user