mirror of
https://github.com/sysprog21/lkmpg.git
synced 2025-02-26 14:44:09 +08:00
deploy: 6110f8ee3cbcc8b242f1d1f9a7f784583f2e5efd
This commit is contained in:
parent
1285092a41
commit
0a2e161bc9
98
index.html
98
index.html
@ -4497,21 +4497,21 @@ 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. 1557 --><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 interrupt handler itself, because the system is in an
|
||||
unknown state. The solution to this problem is for the interrupt handler to
|
||||
do what needs to be done immediately, usually read something from the
|
||||
hardware or send something to the hardware, and then schedule the handling of
|
||||
the new information at a later time (this is called the "bottom half") and
|
||||
return. The kernel is then guaranteed to call the bottom half as soon as
|
||||
possible – and when it does, everything allowed in kernel modules will be
|
||||
allowed.
|
||||
</p><!-- l. 1563 --><p class='indent'> The way to implement this is to call
|
||||
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
|
||||
interrupt handler itself, because the system is in an unknown state. Linux kernel
|
||||
solves the problem by splitting interrupt handling into two parts. The first
|
||||
part executes right away and mask the interrupt line. Hardware interrupts
|
||||
must be handled quick, and that is why we need the second part to handle
|
||||
the heavy work deferred from a 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. 1567 --><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. 1565 --><p class='indent'> In practice IRQ handling can be a bit more complex. Hardware is often
|
||||
</p><!-- l. 1569 --><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
|
||||
@ -4528,7 +4528,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. 1574 --><p class='indent'> This function receives the IRQ number, the name of the function,
|
||||
</p><!-- l. 1578 --><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
|
||||
@ -4538,16 +4538,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. 1580 --><p class='noindent'>
|
||||
</p><!-- l. 1584 --><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. 1582 --><p class='noindent'>Many popular single board computers, such as Raspberry Pi or Beagleboards, have a
|
||||
<!-- l. 1586 --><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. 1586 --><p class='indent'> Here is an example where buttons are connected to GPIO numbers 17 and 18 and
|
||||
</p><!-- l. 1590 --><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'>
|
||||
@ -4697,14 +4697,14 @@ appropriate for your board.
|
||||
<a id='x1-57286r143'></a><span class='ecrm-0500'>143</span>
|
||||
<a id='x1-57288r144'></a><span class='ecrm-0500'>144</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor2395'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span>
|
||||
<a id='x1-57290r145'></a><span class='ecrm-0500'>145</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor2396'><span class='ectt-0800'>"Handle some GPIO interrupts"</span></span><span class='ectt-0800'>);</span></pre>
|
||||
<!-- l. 1591 --><p class='noindent'>
|
||||
<!-- l. 1595 --><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. 1593 --><p class='noindent'>Suppose you want to do a bunch of stuff inside of an interrupt routine. A common
|
||||
<!-- l. 1597 --><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. 1597 --><p class='indent'> The example below modifies the previous example to also run an additional task
|
||||
</p><!-- l. 1601 --><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'>
|
||||
|
||||
@ -4879,19 +4879,19 @@ when an interrupt is triggered.
|
||||
<a id='x1-58332r166'></a><span class='ecrm-0500'>166</span>
|
||||
<a id='x1-58334r167'></a><span class='ecrm-0500'>167</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor2523'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span>
|
||||
<a id='x1-58336r168'></a><span class='ecrm-0500'>168</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor2524'><span class='ectt-0800'>"Interrupt with top and bottom half"</span></span><span class='ectt-0800'>);</span></pre>
|
||||
<!-- l. 1601 --><p class='noindent'>
|
||||
<!-- l. 1605 --><p class='noindent'>
|
||||
</p>
|
||||
<h3 class='sectionHead' id='crypto'><span class='titlemark'>16 </span> <a id='x1-5900016'></a>Crypto</h3>
|
||||
<!-- l. 1603 --><p class='noindent'>At the dawn of the internet, everybody trusted everybody completely…but that did
|
||||
<!-- l. 1607 --><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. 1608 --><p class='noindent'>
|
||||
</p><!-- l. 1612 --><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. 1611 --><p class='noindent'>Calculating and checking the hashes of things is a common operation. Here is a
|
||||
<!-- l. 1615 --><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>
|
||||
@ -4957,21 +4957,21 @@ demonstration of how to calculate a sha256 hash within a kernel module.
|
||||
<a id='x1-60120r60'></a><span class='ecrm-0500'>60</span>
|
||||
<a id='x1-60122r61'></a><span class='ecrm-0500'>61</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor2574'><span class='ectt-0800'>"sha256 hash test"</span></span><span class='ectt-0800'>);</span>
|
||||
<a id='x1-60124r62'></a><span class='ecrm-0500'>62</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor2575'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
||||
<!-- l. 1616 --><p class='indent'> Make and install the module:
|
||||
<!-- l. 1620 --><p class='indent'> Make and install the module:
|
||||
</p><!-- l. 1 --><p class='indent'>
|
||||
</p>
|
||||
<pre class='fancyvrb' id='fancyvrb68'><a id='x1-60129r1'></a><span class='ecrm-0500'>1</span><span class='ectt-1000'>make</span>
|
||||
<a id='x1-60131r2'></a><span class='ecrm-0500'>2</span><span class='ectt-1000'>sudo insmod cryptosha256.ko</span>
|
||||
<a id='x1-60133r3'></a><span class='ecrm-0500'>3</span><span class='ectt-1000'>dmesg</span></pre>
|
||||
<!-- l. 1624 --><p class='indent'> And you should see that the hash was calculated for the test string.
|
||||
</p><!-- l. 1626 --><p class='indent'> Finally, remove the test module:
|
||||
<!-- l. 1628 --><p class='indent'> And you should see that the hash was calculated for the test string.
|
||||
</p><!-- l. 1630 --><p class='indent'> Finally, remove the test module:
|
||||
</p><!-- l. 1 --><p class='indent'>
|
||||
</p>
|
||||
<pre class='fancyvrb' id='fancyvrb69'><a id='x1-60136r1'></a><span class='ecrm-0500'>1</span><span class='ectt-1000'>sudo rmmod cryptosha256</span></pre>
|
||||
<!-- l. 1632 --><p class='noindent'>
|
||||
<!-- l. 1636 --><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. 1634 --><p class='noindent'>Here is an example of symmetrically encrypting a string using the AES algorithm
|
||||
<!-- l. 1638 --><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'>
|
||||
|
||||
@ -5177,10 +5177,10 @@ and a password.
|
||||
<a id='x1-61394r197'></a><span class='ecrm-0500'>197</span>
|
||||
<a id='x1-61396r198'></a><span class='ecrm-0500'>198</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor2725'><span class='ectt-0800'>"Symmetric key encryption example"</span></span><span class='ectt-0800'>);</span>
|
||||
<a id='x1-61398r199'></a><span class='ecrm-0500'>199</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor2726'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
||||
<!-- l. 1638 --><p class='noindent'>
|
||||
<!-- l. 1642 --><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. 1640 --><p class='noindent'>Up to this point we have seen all kinds of modules doing all kinds of things, but there
|
||||
<!-- l. 1644 --><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
|
||||
@ -5287,13 +5287,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='textcolor2801'><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='textcolor2802'><span class='ectt-0800'>"Linux Device Model example"</span></span><span class='ectt-0800'>);</span></pre>
|
||||
<!-- l. 1646 --><p class='noindent'>
|
||||
<!-- l. 1650 --><p class='noindent'>
|
||||
</p>
|
||||
<h3 class='sectionHead' id='optimizations'><span class='titlemark'>18 </span> <a id='x1-6300018'></a>Optimizations</h3>
|
||||
<!-- l. 1648 --><p class='noindent'>
|
||||
<!-- l. 1652 --><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. 1650 --><p class='noindent'>Sometimes you might want your code to run as quickly as possible,
|
||||
<!-- l. 1654 --><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
|
||||
@ -5315,35 +5315,35 @@ to succeed.
|
||||
|
||||
|
||||
|
||||
<!-- l. 1664 --><p class='indent'> When the <code> <span class='ectt-1000'>unlikely</span>
|
||||
<!-- l. 1668 --><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. 1668 --><p class='noindent'>
|
||||
</p><!-- l. 1672 --><p class='noindent'>
|
||||
</p>
|
||||
<h3 class='sectionHead' id='common-pitfalls'><span class='titlemark'>19 </span> <a id='x1-6500019'></a>Common Pitfalls</h3>
|
||||
<!-- l. 1671 --><p class='noindent'>
|
||||
<!-- l. 1675 --><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. 1673 --><p class='noindent'>You can not do that. In a kernel module, you can only use kernel functions which are
|
||||
<!-- l. 1677 --><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. 1676 --><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. 1678 --><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. 1680 --><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. 1682 --><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. 1684 --><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. 1682 --><p class='noindent'>For people seriously interested in kernel programming, I recommend <a href='https://kernelnewbies.org'>kernelnewbies.org</a>
|
||||
<!-- l. 1686 --><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. 1685 --><p class='indent'> If you are interested in more examples of short kernel modules then searching on
|
||||
</p><!-- l. 1689 --><p class='indent'> If you are interested in more examples of short kernel modules then searching on
|
||||
sites such as Github and Gitlab is a good way to start, although there is a lot of
|
||||
duplication of older LKMPG examples which may not compile with newer kernel
|
||||
versions. You will also be able to find examples of the use of kernel modules to attack
|
||||
@ -5353,12 +5353,12 @@ kernel.
|
||||
|
||||
|
||||
|
||||
</p><!-- l. 1688 --><p class='indent'> I hope I have helped you in your quest to become a better programmer, or at
|
||||
</p><!-- l. 1692 --><p class='indent'> I hope I have helped you in your quest to become a better programmer, or at
|
||||
least to have fun through technology. And, if you do write useful kernel modules, I
|
||||
hope you publish them under the GPL, so I can use them too.
|
||||
</p><!-- l. 1691 --><p class='indent'> If you would like to contribute to this guide or notice anything glaringly wrong,
|
||||
</p><!-- l. 1695 --><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>.
|
||||
</p><!-- l. 1693 --><p class='indent'> Happy hacking!
|
||||
</p><!-- l. 1697 --><p class='indent'> Happy hacking!
|
||||
</p>
|
||||
<div class='footnotes'><!-- l. 1526 --><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
|
||||
|
@ -4497,21 +4497,21 @@ 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. 1557 --><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 interrupt handler itself, because the system is in an
|
||||
unknown state. The solution to this problem is for the interrupt handler to
|
||||
do what needs to be done immediately, usually read something from the
|
||||
hardware or send something to the hardware, and then schedule the handling of
|
||||
the new information at a later time (this is called the "bottom half") and
|
||||
return. The kernel is then guaranteed to call the bottom half as soon as
|
||||
possible – and when it does, everything allowed in kernel modules will be
|
||||
allowed.
|
||||
</p><!-- l. 1563 --><p class='indent'> The way to implement this is to call
|
||||
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
|
||||
interrupt handler itself, because the system is in an unknown state. Linux kernel
|
||||
solves the problem by splitting interrupt handling into two parts. The first
|
||||
part executes right away and mask the interrupt line. Hardware interrupts
|
||||
must be handled quick, and that is why we need the second part to handle
|
||||
the heavy work deferred from a 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. 1567 --><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. 1565 --><p class='indent'> In practice IRQ handling can be a bit more complex. Hardware is often
|
||||
</p><!-- l. 1569 --><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
|
||||
@ -4528,7 +4528,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. 1574 --><p class='indent'> This function receives the IRQ number, the name of the function,
|
||||
</p><!-- l. 1578 --><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
|
||||
@ -4538,16 +4538,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. 1580 --><p class='noindent'>
|
||||
</p><!-- l. 1584 --><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. 1582 --><p class='noindent'>Many popular single board computers, such as Raspberry Pi or Beagleboards, have a
|
||||
<!-- l. 1586 --><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. 1586 --><p class='indent'> Here is an example where buttons are connected to GPIO numbers 17 and 18 and
|
||||
</p><!-- l. 1590 --><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'>
|
||||
@ -4697,14 +4697,14 @@ appropriate for your board.
|
||||
<a id='x1-57286r143'></a><span class='ecrm-0500'>143</span>
|
||||
<a id='x1-57288r144'></a><span class='ecrm-0500'>144</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor2395'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span>
|
||||
<a id='x1-57290r145'></a><span class='ecrm-0500'>145</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor2396'><span class='ectt-0800'>"Handle some GPIO interrupts"</span></span><span class='ectt-0800'>);</span></pre>
|
||||
<!-- l. 1591 --><p class='noindent'>
|
||||
<!-- l. 1595 --><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. 1593 --><p class='noindent'>Suppose you want to do a bunch of stuff inside of an interrupt routine. A common
|
||||
<!-- l. 1597 --><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. 1597 --><p class='indent'> The example below modifies the previous example to also run an additional task
|
||||
</p><!-- l. 1601 --><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'>
|
||||
|
||||
@ -4879,19 +4879,19 @@ when an interrupt is triggered.
|
||||
<a id='x1-58332r166'></a><span class='ecrm-0500'>166</span>
|
||||
<a id='x1-58334r167'></a><span class='ecrm-0500'>167</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor2523'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span>
|
||||
<a id='x1-58336r168'></a><span class='ecrm-0500'>168</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor2524'><span class='ectt-0800'>"Interrupt with top and bottom half"</span></span><span class='ectt-0800'>);</span></pre>
|
||||
<!-- l. 1601 --><p class='noindent'>
|
||||
<!-- l. 1605 --><p class='noindent'>
|
||||
</p>
|
||||
<h3 class='sectionHead' id='crypto'><span class='titlemark'>16 </span> <a id='x1-5900016'></a>Crypto</h3>
|
||||
<!-- l. 1603 --><p class='noindent'>At the dawn of the internet, everybody trusted everybody completely…but that did
|
||||
<!-- l. 1607 --><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. 1608 --><p class='noindent'>
|
||||
</p><!-- l. 1612 --><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. 1611 --><p class='noindent'>Calculating and checking the hashes of things is a common operation. Here is a
|
||||
<!-- l. 1615 --><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>
|
||||
@ -4957,21 +4957,21 @@ demonstration of how to calculate a sha256 hash within a kernel module.
|
||||
<a id='x1-60120r60'></a><span class='ecrm-0500'>60</span>
|
||||
<a id='x1-60122r61'></a><span class='ecrm-0500'>61</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor2574'><span class='ectt-0800'>"sha256 hash test"</span></span><span class='ectt-0800'>);</span>
|
||||
<a id='x1-60124r62'></a><span class='ecrm-0500'>62</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor2575'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
||||
<!-- l. 1616 --><p class='indent'> Make and install the module:
|
||||
<!-- l. 1620 --><p class='indent'> Make and install the module:
|
||||
</p><!-- l. 1 --><p class='indent'>
|
||||
</p>
|
||||
<pre class='fancyvrb' id='fancyvrb68'><a id='x1-60129r1'></a><span class='ecrm-0500'>1</span><span class='ectt-1000'>make</span>
|
||||
<a id='x1-60131r2'></a><span class='ecrm-0500'>2</span><span class='ectt-1000'>sudo insmod cryptosha256.ko</span>
|
||||
<a id='x1-60133r3'></a><span class='ecrm-0500'>3</span><span class='ectt-1000'>dmesg</span></pre>
|
||||
<!-- l. 1624 --><p class='indent'> And you should see that the hash was calculated for the test string.
|
||||
</p><!-- l. 1626 --><p class='indent'> Finally, remove the test module:
|
||||
<!-- l. 1628 --><p class='indent'> And you should see that the hash was calculated for the test string.
|
||||
</p><!-- l. 1630 --><p class='indent'> Finally, remove the test module:
|
||||
</p><!-- l. 1 --><p class='indent'>
|
||||
</p>
|
||||
<pre class='fancyvrb' id='fancyvrb69'><a id='x1-60136r1'></a><span class='ecrm-0500'>1</span><span class='ectt-1000'>sudo rmmod cryptosha256</span></pre>
|
||||
<!-- l. 1632 --><p class='noindent'>
|
||||
<!-- l. 1636 --><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. 1634 --><p class='noindent'>Here is an example of symmetrically encrypting a string using the AES algorithm
|
||||
<!-- l. 1638 --><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'>
|
||||
|
||||
@ -5177,10 +5177,10 @@ and a password.
|
||||
<a id='x1-61394r197'></a><span class='ecrm-0500'>197</span>
|
||||
<a id='x1-61396r198'></a><span class='ecrm-0500'>198</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor2725'><span class='ectt-0800'>"Symmetric key encryption example"</span></span><span class='ectt-0800'>);</span>
|
||||
<a id='x1-61398r199'></a><span class='ecrm-0500'>199</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor2726'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
||||
<!-- l. 1638 --><p class='noindent'>
|
||||
<!-- l. 1642 --><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. 1640 --><p class='noindent'>Up to this point we have seen all kinds of modules doing all kinds of things, but there
|
||||
<!-- l. 1644 --><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
|
||||
@ -5287,13 +5287,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='textcolor2801'><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='textcolor2802'><span class='ectt-0800'>"Linux Device Model example"</span></span><span class='ectt-0800'>);</span></pre>
|
||||
<!-- l. 1646 --><p class='noindent'>
|
||||
<!-- l. 1650 --><p class='noindent'>
|
||||
</p>
|
||||
<h3 class='sectionHead' id='optimizations'><span class='titlemark'>18 </span> <a id='x1-6300018'></a>Optimizations</h3>
|
||||
<!-- l. 1648 --><p class='noindent'>
|
||||
<!-- l. 1652 --><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. 1650 --><p class='noindent'>Sometimes you might want your code to run as quickly as possible,
|
||||
<!-- l. 1654 --><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
|
||||
@ -5315,35 +5315,35 @@ to succeed.
|
||||
|
||||
|
||||
|
||||
<!-- l. 1664 --><p class='indent'> When the <code> <span class='ectt-1000'>unlikely</span>
|
||||
<!-- l. 1668 --><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. 1668 --><p class='noindent'>
|
||||
</p><!-- l. 1672 --><p class='noindent'>
|
||||
</p>
|
||||
<h3 class='sectionHead' id='common-pitfalls'><span class='titlemark'>19 </span> <a id='x1-6500019'></a>Common Pitfalls</h3>
|
||||
<!-- l. 1671 --><p class='noindent'>
|
||||
<!-- l. 1675 --><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. 1673 --><p class='noindent'>You can not do that. In a kernel module, you can only use kernel functions which are
|
||||
<!-- l. 1677 --><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. 1676 --><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. 1678 --><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. 1680 --><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. 1682 --><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. 1684 --><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. 1682 --><p class='noindent'>For people seriously interested in kernel programming, I recommend <a href='https://kernelnewbies.org'>kernelnewbies.org</a>
|
||||
<!-- l. 1686 --><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. 1685 --><p class='indent'> If you are interested in more examples of short kernel modules then searching on
|
||||
</p><!-- l. 1689 --><p class='indent'> If you are interested in more examples of short kernel modules then searching on
|
||||
sites such as Github and Gitlab is a good way to start, although there is a lot of
|
||||
duplication of older LKMPG examples which may not compile with newer kernel
|
||||
versions. You will also be able to find examples of the use of kernel modules to attack
|
||||
@ -5353,12 +5353,12 @@ kernel.
|
||||
|
||||
|
||||
|
||||
</p><!-- l. 1688 --><p class='indent'> I hope I have helped you in your quest to become a better programmer, or at
|
||||
</p><!-- l. 1692 --><p class='indent'> I hope I have helped you in your quest to become a better programmer, or at
|
||||
least to have fun through technology. And, if you do write useful kernel modules, I
|
||||
hope you publish them under the GPL, so I can use them too.
|
||||
</p><!-- l. 1691 --><p class='indent'> If you would like to contribute to this guide or notice anything glaringly wrong,
|
||||
</p><!-- l. 1695 --><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>.
|
||||
</p><!-- l. 1693 --><p class='indent'> Happy hacking!
|
||||
</p><!-- l. 1697 --><p class='indent'> Happy hacking!
|
||||
</p>
|
||||
<div class='footnotes'><!-- l. 1526 --><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
|
||||
|
Loading…
x
Reference in New Issue
Block a user