mirror of
https://github.com/sysprog21/lkmpg.git
synced 2025-02-27 03:02:10 +08:00
deploy: c8238430b2b6a63385e721f00882a2f5111d0d86
This commit is contained in:
parent
c7d304491a
commit
2898c1778c
138
index.html
138
index.html
@ -3740,7 +3740,7 @@ they will not be forgotten and will activate when the unlock happens, using the
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='read-and-write-locks'><span class='titlemark'>0.12.3 </span> <a id='x1-470000.12.3'></a>Read and write locks</h4>
|
||||
<!-- l. 1351 --><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
|
||||
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
|
||||
then they would not disrupt the logic. As before it is a good idea to keep
|
||||
@ -3811,7 +3811,7 @@ which could possibly interfere with your logic then you can use the simpler
|
||||
</code> or the corresponding write functions.
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='atomic-operations'><span class='titlemark'>0.12.4 </span> <a id='x1-480000.12.4'></a>Atomic operations</h4>
|
||||
<!-- l. 1360 --><p class='noindent'>If you are doing simple arithmetic: adding, subtracting or bitwise operations then
|
||||
<!-- l. 1360 --><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
|
||||
@ -3903,14 +3903,14 @@ below.
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='replacement'><span class='titlemark'>0.13.1 </span> <a id='x1-500000.13.1'></a>Replacement</h4>
|
||||
<!-- l. 1371 --><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
|
||||
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. 1374 --><p class='indent'> "tty" is an abbreviation of <span class='ecti-1000'>teletype</span>: originally a combination keyboard-printer
|
||||
</p><!-- l. 1375 --><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. 1376 --><p class='indent'> The way this is done is by using current, a pointer to the currently running task,
|
||||
</p><!-- l. 1377 --><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.
|
||||
@ -3993,16 +3993,16 @@ tty.
|
||||
<a id='x1-50150r75'></a><span class='ecrm-0500'>75</span><span class='ectt-0800'>module_exit(print_string_exit);</span>
|
||||
<a id='x1-50152r76'></a><span class='ecrm-0500'>76</span>
|
||||
<a id='x1-50154r77'></a><span class='ecrm-0500'>77</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor2033'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
||||
<!-- l. 1381 --><p class='noindent'>
|
||||
<!-- l. 1382 --><p class='noindent'>
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='flashing-keyboard-leds'><span class='titlemark'>0.13.2 </span> <a id='x1-510000.13.2'></a>Flashing keyboard LEDs</h4>
|
||||
<!-- l. 1383 --><p class='noindent'>In certain conditions, you may desire a simpler and more direct way to communicate
|
||||
<!-- l. 1384 --><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. 1387 --><p class='indent'> The following source code illustrates a minimal kernel module which, when
|
||||
</p><!-- l. 1388 --><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>
|
||||
@ -4098,33 +4098,33 @@ loaded, starts blinking the keyboard LEDs until it is unloaded.
|
||||
|
||||
|
||||
|
||||
<!-- l. 1391 --><p class='indent'> If none of the examples in this chapter fit your debugging needs
|
||||
<!-- l. 1392 --><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>
|
||||
</code> is good for? If you activate that you get low level access to the serial port. While this
|
||||
might not sound very powerful by itself, you can patch <a href='https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/kernel/printk.c'>kernel/printk.c</a> or any other
|
||||
essential syscall to print ASCII characters, thus makeing it possible to trace virtually
|
||||
essential syscall to print ASCII characters, thus making it possible to trace virtually
|
||||
everything what your code does over a serial line. If you find yourself porting the
|
||||
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. 1398 --><p class='indent'> While you have seen lots of stuff that can be used to aid debugging here, there are
|
||||
</p><!-- l. 1399 --><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. 1402 --><p class='noindent'>
|
||||
</p><!-- l. 1403 --><p class='noindent'>
|
||||
</p>
|
||||
<h3 class='sectionHead' id='scheduling-tasks'><span class='titlemark'>0.14 </span> <a id='x1-520000.14'></a>Scheduling Tasks</h3>
|
||||
<!-- l. 1404 --><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
|
||||
<!-- l. 1405 --><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. 1407 --><p class='noindent'>
|
||||
</p><!-- l. 1409 --><p class='noindent'>
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='tasklets'><span class='titlemark'>0.14.1 </span> <a id='x1-530000.14.1'></a>Tasklets</h4>
|
||||
<!-- l. 1409 --><p class='noindent'>Here is an example tasklet module. The
|
||||
<!-- l. 1411 --><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>
|
||||
@ -4168,7 +4168,7 @@ better suited to running multiple things in a sequence.
|
||||
<a id='x1-53072r35'></a><span class='ecrm-0500'>35</span>
|
||||
<a id='x1-53074r36'></a><span class='ecrm-0500'>36</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor2153'><span class='ectt-0800'>"Tasklet example"</span></span><span class='ectt-0800'>);</span>
|
||||
<a id='x1-53076r37'></a><span class='ecrm-0500'>37</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor2154'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
||||
<!-- l. 1414 --><p class='indent'> So with this example loaded <code> <span class='ectt-1000'>dmesg</span>
|
||||
<!-- l. 1416 --><p class='indent'> So with this example loaded <code> <span class='ectt-1000'>dmesg</span>
|
||||
</code> should show:
|
||||
|
||||
|
||||
@ -4180,11 +4180,11 @@ Example tasklet starts
|
||||
Example tasklet init continues...
|
||||
Example tasklet ends
|
||||
</pre>
|
||||
<!-- l. 1421 --><p class='nopar'>
|
||||
</p><!-- l. 1423 --><p class='noindent'>
|
||||
<!-- l. 1423 --><p class='nopar'>
|
||||
</p><!-- l. 1425 --><p class='noindent'>
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='work-queues'><span class='titlemark'>0.14.2 </span> <a id='x1-540000.14.2'></a>Work queues</h4>
|
||||
<!-- l. 1425 --><p class='noindent'>To add a task to the scheduler we can use a workqueue. The kernel then uses the
|
||||
<!-- l. 1427 --><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>
|
||||
@ -4222,21 +4222,21 @@ Completely Fair Scheduler (CFS) to execute work within the queue.
|
||||
<a id='x1-54064r32'></a><span class='ecrm-0500'>32</span>
|
||||
<a id='x1-54066r33'></a><span class='ecrm-0500'>33</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor2182'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span>
|
||||
<a id='x1-54068r34'></a><span class='ecrm-0500'>34</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor2183'><span class='ectt-0800'>"Workqueue example"</span></span><span class='ectt-0800'>);</span></pre>
|
||||
<!-- l. 1430 --><p class='noindent'>
|
||||
</p>
|
||||
<h3 class='sectionHead' id='interrupt-handlers'><span class='titlemark'>0.15 </span> <a id='x1-550000.15'></a>Interrupt Handlers</h3>
|
||||
<!-- l. 1432 --><p class='noindent'>
|
||||
</p>
|
||||
<h3 class='sectionHead' id='interrupt-handlers'><span class='titlemark'>0.15 </span> <a id='x1-550000.15'></a>Interrupt Handlers</h3>
|
||||
<!-- l. 1434 --><p class='noindent'>
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='interrupt-handlers1'><span class='titlemark'>0.15.1 </span> <a id='x1-560000.15.1'></a>Interrupt Handlers</h4>
|
||||
<!-- l. 1434 --><p class='noindent'>Except for the last chapter, everything we did in the kernel so far we have done as a
|
||||
<!-- l. 1436 --><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. 1438 --><p class='indent'> There are two types of interaction between the CPU and the rest of the
|
||||
</p><!-- l. 1440 --><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 other is when the hardware needs to tell the CPU something. The second, called
|
||||
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
|
||||
@ -4244,14 +4244,14 @@ lost.
|
||||
|
||||
|
||||
|
||||
</p><!-- l. 1443 --><p class='indent'> Under Linux, hardware interrupts are called IRQ’s (Interrupt ReQuests). There
|
||||
</p><!-- l. 1445 --><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. 1449 --><p class='indent'> When the CPU receives an interrupt, it stops whatever it is doing (unless it is
|
||||
</p><!-- l. 1451 --><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
|
||||
@ -4263,10 +4263,10 @@ 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. 1455 --><p class='indent'> The way to implement this is to call
|
||||
</p><!-- l. 1457 --><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. 1457 --><p class='indent'> In practice IRQ handling can be a bit more complex. Hardware is often
|
||||
</p><!-- l. 1459 --><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
|
||||
@ -4280,8 +4280,8 @@ need to solve another truckload of problems. It is not enough to know if
|
||||
a certain IRQs has happend, it’s also important for what CPU(s) it was
|
||||
for. People still interested in more details, might want to refer to "APIC"
|
||||
now.
|
||||
</p><!-- l. 1466 --><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 pass to the
|
||||
</p><!-- l. 1468 --><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
|
||||
<code> <span class='ectt-1000'>SA_SHIRQ</span>
|
||||
@ -4293,16 +4293,16 @@ already a handler on this IRQ, or if you are both willing to share.
|
||||
|
||||
|
||||
|
||||
</p><!-- l. 1472 --><p class='noindent'>
|
||||
</p><!-- l. 1474 --><p class='noindent'>
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='detecting-button-presses'><span class='titlemark'>0.15.2 </span> <a id='x1-570000.15.2'></a>Detecting button presses</h4>
|
||||
<!-- l. 1474 --><p class='noindent'>Many popular single board computers, such as Raspberry Pi or Beagleboards, have a
|
||||
<!-- l. 1476 --><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
|
||||
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. 1478 --><p class='indent'> Here is an example where buttons are connected to GPIO numbers 17 and 18 and
|
||||
</p><!-- l. 1480 --><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'>
|
||||
@ -4452,14 +4452,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='textcolor2290'><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='textcolor2291'><span class='ectt-0800'>"Handle some GPIO interrupts"</span></span><span class='ectt-0800'>);</span></pre>
|
||||
<!-- l. 1483 --><p class='noindent'>
|
||||
<!-- l. 1485 --><p class='noindent'>
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='bottom-half'><span class='titlemark'>0.15.3 </span> <a id='x1-580000.15.3'></a>Bottom Half</h4>
|
||||
<!-- l. 1485 --><p class='noindent'>Suppose you want to do a bunch of stuff inside of an interrupt routine. A common
|
||||
<!-- l. 1487 --><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. 1489 --><p class='indent'> The example below modifies the previous example to also run an additional task
|
||||
</p><!-- l. 1491 --><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'>
|
||||
</p>
|
||||
@ -4624,22 +4624,22 @@ when an interrupt is triggered.
|
||||
<a id='x1-58318r159'></a><span class='ecrm-0500'>159</span>
|
||||
<a id='x1-58320r160'></a><span class='ecrm-0500'>160</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor2412'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span>
|
||||
<a id='x1-58322r161'></a><span class='ecrm-0500'>161</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor2413'><span class='ectt-0800'>"Interrupt with top and bottom half"</span></span><span class='ectt-0800'>);</span></pre>
|
||||
<!-- l. 1493 --><p class='noindent'>
|
||||
<!-- l. 1495 --><p class='noindent'>
|
||||
</p>
|
||||
<h3 class='sectionHead' id='crypto'><span class='titlemark'>0.16 </span> <a id='x1-590000.16'></a>Crypto</h3>
|
||||
<!-- l. 1495 --><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
|
||||
<!-- l. 1497 --><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
|
||||
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. 1500 --><p class='noindent'>
|
||||
</p><!-- l. 1502 --><p class='noindent'>
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='hash-functions'><span class='titlemark'>0.16.1 </span> <a id='x1-600000.16.1'></a>Hash functions</h4>
|
||||
<!-- l. 1503 --><p class='noindent'>Calculating and checking the hashes of things is a common operation. Here is a
|
||||
<!-- l. 1505 --><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>
|
||||
@ -4705,21 +4705,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='textcolor2463'><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='textcolor2464'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
||||
<!-- l. 1508 --><p class='indent'> Make and install the module:
|
||||
<!-- l. 1510 --><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. 1516 --><p class='indent'> And you should see that the hash was calculated for the test string.
|
||||
</p><!-- l. 1518 --><p class='indent'> Finally, remove the test module:
|
||||
<!-- l. 1518 --><p class='indent'> And you should see that the hash was calculated for the test string.
|
||||
</p><!-- l. 1520 --><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. 1524 --><p class='noindent'>
|
||||
<!-- l. 1526 --><p class='noindent'>
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='symmetric-key-encryption'><span class='titlemark'>0.16.2 </span> <a id='x1-610000.16.2'></a>Symmetric key encryption</h4>
|
||||
<!-- l. 1526 --><p class='noindent'>Here is an example of symmetrically encrypting a string using the AES algorithm
|
||||
<!-- l. 1528 --><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'>
|
||||
</p>
|
||||
@ -4920,10 +4920,10 @@ and a password.
|
||||
<a id='x1-61390r195'></a><span class='ecrm-0500'>195</span>
|
||||
<a id='x1-61392r196'></a><span class='ecrm-0500'>196</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor2610'><span class='ectt-0800'>"Symmetric key encryption example"</span></span><span class='ectt-0800'>);</span>
|
||||
<a id='x1-61394r197'></a><span class='ecrm-0500'>197</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor2611'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
||||
<!-- l. 1530 --><p class='noindent'>
|
||||
<!-- l. 1532 --><p class='noindent'>
|
||||
</p>
|
||||
<h3 class='sectionHead' id='standardizing-the-interfaces-the-device-model'><span class='titlemark'>0.17 </span> <a id='x1-620000.17'></a>Standardizing the interfaces: The Device Model</h3>
|
||||
<!-- l. 1532 --><p class='noindent'>Up to this point we have seen all kinds of modules doing all kinds of things, but there
|
||||
<!-- l. 1534 --><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 show below, and you can
|
||||
@ -5033,13 +5033,13 @@ functions.
|
||||
|
||||
|
||||
|
||||
<!-- l. 1538 --><p class='noindent'>
|
||||
</p>
|
||||
<h3 class='sectionHead' id='optimizations'><span class='titlemark'>0.18 </span> <a id='x1-630000.18'></a>Optimizations</h3>
|
||||
<!-- l. 1540 --><p class='noindent'>
|
||||
</p>
|
||||
<h3 class='sectionHead' id='optimizations'><span class='titlemark'>0.18 </span> <a id='x1-630000.18'></a>Optimizations</h3>
|
||||
<!-- l. 1542 --><p class='noindent'>
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='likely-and-unlikely-conditions'><span class='titlemark'>0.18.1 </span> <a id='x1-640000.18.1'></a>Likely and Unlikely conditions</h4>
|
||||
<!-- l. 1542 --><p class='noindent'>Sometimes you might want your code to run as quickly as possible,
|
||||
<!-- l. 1544 --><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 noticible latency. If your code contains boolean conditions and if you
|
||||
know that the conditions are almost always likely to evaluate as either
|
||||
@ -5049,7 +5049,7 @@ know that the conditions are almost always likely to evaluate as either
|
||||
<code> <span class='ectt-1000'>likely</span>
|
||||
</code> and <code> <span class='ectt-1000'>unlikely</span>
|
||||
</code> macros.
|
||||
</p><!-- l. 1546 --><p class='indent'> For example, when allocating memory you are almost always expecting this to
|
||||
</p><!-- l. 1548 --><p class='indent'> For example, when allocating memory you are almost always expecting this to
|
||||
succeed.
|
||||
</p><!-- l. 1 --><p class='indent'>
|
||||
</p>
|
||||
@ -5059,50 +5059,50 @@ succeed.
|
||||
<a id='x1-64018r4'></a><span class='ecrm-0500'>4</span><span class='ectt-0800'> bio = NULL;</span>
|
||||
<a id='x1-64020r5'></a><span class='ecrm-0500'>5</span><span class='ectt-0800'> </span><span id='textcolor2689'><span class='ectt-0800'>goto</span></span><span class='ectt-0800'> out;</span>
|
||||
<a id='x1-64022r6'></a><span class='ecrm-0500'>6</span><span class='ectt-0800'>}</span></pre>
|
||||
<!-- l. 1557 --><p class='indent'> When the <code> <span class='ectt-1000'>unlikely</span>
|
||||
<!-- l. 1559 --><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. 1561 --><p class='noindent'>
|
||||
</p><!-- l. 1563 --><p class='noindent'>
|
||||
</p>
|
||||
<h3 class='sectionHead' id='common-pitfalls'><span class='titlemark'>0.19 </span> <a id='x1-650000.19'></a>Common Pitfalls</h3>
|
||||
<!-- l. 1564 --><p class='noindent'>
|
||||
<!-- l. 1566 --><p class='noindent'>
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='using-standard-libraries'><span class='titlemark'>0.19.1 </span> <a id='x1-660000.19.1'></a>Using standard libraries</h4>
|
||||
<!-- l. 1566 --><p class='noindent'>You can not do that. In a kernel module you can only use kernel functions, which are
|
||||
<!-- l. 1568 --><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. 1569 --><p class='noindent'>
|
||||
</p><!-- l. 1571 --><p class='noindent'>
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='disabling-interrupts'><span class='titlemark'>0.19.2 </span> <a id='x1-670000.19.2'></a>Disabling interrupts</h4>
|
||||
<!-- l. 1571 --><p class='noindent'>You might need to do this for a short time and that is OK, but if you do not enable
|
||||
<!-- l. 1573 --><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. 1573 --><p class='noindent'>
|
||||
</p><!-- l. 1575 --><p class='noindent'>
|
||||
</p>
|
||||
<h3 class='sectionHead' id='where-to-go-from-here'><span class='titlemark'>0.20 </span> <a id='x1-680000.20'></a>Where To Go From Here?</h3>
|
||||
<!-- l. 1575 --><p class='noindent'>For people seriously interested in kernel programming, I recommend <a href='https://kernelnewbies.org'>kernelnewbies.org</a>
|
||||
<!-- l. 1577 --><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. 1578 --><p class='indent'> If you are interested in more examples of short kernel modules then searching on
|
||||
</p><!-- l. 1580 --><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
|
||||
or compromise systems or exfiltrate data and those can be useful for thinking about
|
||||
how to defend systems and learning about existing security mechanisms within the
|
||||
kernel.
|
||||
</p><!-- l. 1581 --><p class='indent'> I hope I have helped you in your quest to become a better programmer, or at
|
||||
</p><!-- l. 1583 --><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. 1584 --><p class='indent'> If you would like to contribute to this guide or notice anything glaringly wrong,
|
||||
</p><!-- l. 1586 --><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. 1586 --><p class='indent'> Happy hacking!
|
||||
</p><!-- l. 1588 --><p class='indent'> Happy hacking!
|
||||
</p>
|
||||
|
||||
</body>
|
||||
|
@ -3740,7 +3740,7 @@ they will not be forgotten and will activate when the unlock happens, using the
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='read-and-write-locks'><span class='titlemark'>0.12.3 </span> <a id='x1-470000.12.3'></a>Read and write locks</h4>
|
||||
<!-- l. 1351 --><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
|
||||
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
|
||||
then they would not disrupt the logic. As before it is a good idea to keep
|
||||
@ -3811,7 +3811,7 @@ which could possibly interfere with your logic then you can use the simpler
|
||||
</code> or the corresponding write functions.
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='atomic-operations'><span class='titlemark'>0.12.4 </span> <a id='x1-480000.12.4'></a>Atomic operations</h4>
|
||||
<!-- l. 1360 --><p class='noindent'>If you are doing simple arithmetic: adding, subtracting or bitwise operations then
|
||||
<!-- l. 1360 --><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
|
||||
@ -3903,14 +3903,14 @@ below.
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='replacement'><span class='titlemark'>0.13.1 </span> <a id='x1-500000.13.1'></a>Replacement</h4>
|
||||
<!-- l. 1371 --><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
|
||||
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. 1374 --><p class='indent'> "tty" is an abbreviation of <span class='ecti-1000'>teletype</span>: originally a combination keyboard-printer
|
||||
</p><!-- l. 1375 --><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. 1376 --><p class='indent'> The way this is done is by using current, a pointer to the currently running task,
|
||||
</p><!-- l. 1377 --><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.
|
||||
@ -3993,16 +3993,16 @@ tty.
|
||||
<a id='x1-50150r75'></a><span class='ecrm-0500'>75</span><span class='ectt-0800'>module_exit(print_string_exit);</span>
|
||||
<a id='x1-50152r76'></a><span class='ecrm-0500'>76</span>
|
||||
<a id='x1-50154r77'></a><span class='ecrm-0500'>77</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor2033'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
||||
<!-- l. 1381 --><p class='noindent'>
|
||||
<!-- l. 1382 --><p class='noindent'>
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='flashing-keyboard-leds'><span class='titlemark'>0.13.2 </span> <a id='x1-510000.13.2'></a>Flashing keyboard LEDs</h4>
|
||||
<!-- l. 1383 --><p class='noindent'>In certain conditions, you may desire a simpler and more direct way to communicate
|
||||
<!-- l. 1384 --><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. 1387 --><p class='indent'> The following source code illustrates a minimal kernel module which, when
|
||||
</p><!-- l. 1388 --><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>
|
||||
@ -4098,33 +4098,33 @@ loaded, starts blinking the keyboard LEDs until it is unloaded.
|
||||
|
||||
|
||||
|
||||
<!-- l. 1391 --><p class='indent'> If none of the examples in this chapter fit your debugging needs
|
||||
<!-- l. 1392 --><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>
|
||||
</code> is good for? If you activate that you get low level access to the serial port. While this
|
||||
might not sound very powerful by itself, you can patch <a href='https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/kernel/printk.c'>kernel/printk.c</a> or any other
|
||||
essential syscall to print ASCII characters, thus makeing it possible to trace virtually
|
||||
essential syscall to print ASCII characters, thus making it possible to trace virtually
|
||||
everything what your code does over a serial line. If you find yourself porting the
|
||||
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. 1398 --><p class='indent'> While you have seen lots of stuff that can be used to aid debugging here, there are
|
||||
</p><!-- l. 1399 --><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. 1402 --><p class='noindent'>
|
||||
</p><!-- l. 1403 --><p class='noindent'>
|
||||
</p>
|
||||
<h3 class='sectionHead' id='scheduling-tasks'><span class='titlemark'>0.14 </span> <a id='x1-520000.14'></a>Scheduling Tasks</h3>
|
||||
<!-- l. 1404 --><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
|
||||
<!-- l. 1405 --><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. 1407 --><p class='noindent'>
|
||||
</p><!-- l. 1409 --><p class='noindent'>
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='tasklets'><span class='titlemark'>0.14.1 </span> <a id='x1-530000.14.1'></a>Tasklets</h4>
|
||||
<!-- l. 1409 --><p class='noindent'>Here is an example tasklet module. The
|
||||
<!-- l. 1411 --><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>
|
||||
@ -4168,7 +4168,7 @@ better suited to running multiple things in a sequence.
|
||||
<a id='x1-53072r35'></a><span class='ecrm-0500'>35</span>
|
||||
<a id='x1-53074r36'></a><span class='ecrm-0500'>36</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor2153'><span class='ectt-0800'>"Tasklet example"</span></span><span class='ectt-0800'>);</span>
|
||||
<a id='x1-53076r37'></a><span class='ecrm-0500'>37</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor2154'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
||||
<!-- l. 1414 --><p class='indent'> So with this example loaded <code> <span class='ectt-1000'>dmesg</span>
|
||||
<!-- l. 1416 --><p class='indent'> So with this example loaded <code> <span class='ectt-1000'>dmesg</span>
|
||||
</code> should show:
|
||||
|
||||
|
||||
@ -4180,11 +4180,11 @@ Example tasklet starts
|
||||
Example tasklet init continues...
|
||||
Example tasklet ends
|
||||
</pre>
|
||||
<!-- l. 1421 --><p class='nopar'>
|
||||
</p><!-- l. 1423 --><p class='noindent'>
|
||||
<!-- l. 1423 --><p class='nopar'>
|
||||
</p><!-- l. 1425 --><p class='noindent'>
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='work-queues'><span class='titlemark'>0.14.2 </span> <a id='x1-540000.14.2'></a>Work queues</h4>
|
||||
<!-- l. 1425 --><p class='noindent'>To add a task to the scheduler we can use a workqueue. The kernel then uses the
|
||||
<!-- l. 1427 --><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>
|
||||
@ -4222,21 +4222,21 @@ Completely Fair Scheduler (CFS) to execute work within the queue.
|
||||
<a id='x1-54064r32'></a><span class='ecrm-0500'>32</span>
|
||||
<a id='x1-54066r33'></a><span class='ecrm-0500'>33</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor2182'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span>
|
||||
<a id='x1-54068r34'></a><span class='ecrm-0500'>34</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor2183'><span class='ectt-0800'>"Workqueue example"</span></span><span class='ectt-0800'>);</span></pre>
|
||||
<!-- l. 1430 --><p class='noindent'>
|
||||
</p>
|
||||
<h3 class='sectionHead' id='interrupt-handlers'><span class='titlemark'>0.15 </span> <a id='x1-550000.15'></a>Interrupt Handlers</h3>
|
||||
<!-- l. 1432 --><p class='noindent'>
|
||||
</p>
|
||||
<h3 class='sectionHead' id='interrupt-handlers'><span class='titlemark'>0.15 </span> <a id='x1-550000.15'></a>Interrupt Handlers</h3>
|
||||
<!-- l. 1434 --><p class='noindent'>
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='interrupt-handlers1'><span class='titlemark'>0.15.1 </span> <a id='x1-560000.15.1'></a>Interrupt Handlers</h4>
|
||||
<!-- l. 1434 --><p class='noindent'>Except for the last chapter, everything we did in the kernel so far we have done as a
|
||||
<!-- l. 1436 --><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. 1438 --><p class='indent'> There are two types of interaction between the CPU and the rest of the
|
||||
</p><!-- l. 1440 --><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 other is when the hardware needs to tell the CPU something. The second, called
|
||||
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
|
||||
@ -4244,14 +4244,14 @@ lost.
|
||||
|
||||
|
||||
|
||||
</p><!-- l. 1443 --><p class='indent'> Under Linux, hardware interrupts are called IRQ’s (Interrupt ReQuests). There
|
||||
</p><!-- l. 1445 --><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. 1449 --><p class='indent'> When the CPU receives an interrupt, it stops whatever it is doing (unless it is
|
||||
</p><!-- l. 1451 --><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
|
||||
@ -4263,10 +4263,10 @@ 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. 1455 --><p class='indent'> The way to implement this is to call
|
||||
</p><!-- l. 1457 --><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. 1457 --><p class='indent'> In practice IRQ handling can be a bit more complex. Hardware is often
|
||||
</p><!-- l. 1459 --><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
|
||||
@ -4280,8 +4280,8 @@ need to solve another truckload of problems. It is not enough to know if
|
||||
a certain IRQs has happend, it’s also important for what CPU(s) it was
|
||||
for. People still interested in more details, might want to refer to "APIC"
|
||||
now.
|
||||
</p><!-- l. 1466 --><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 pass to the
|
||||
</p><!-- l. 1468 --><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
|
||||
<code> <span class='ectt-1000'>SA_SHIRQ</span>
|
||||
@ -4293,16 +4293,16 @@ already a handler on this IRQ, or if you are both willing to share.
|
||||
|
||||
|
||||
|
||||
</p><!-- l. 1472 --><p class='noindent'>
|
||||
</p><!-- l. 1474 --><p class='noindent'>
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='detecting-button-presses'><span class='titlemark'>0.15.2 </span> <a id='x1-570000.15.2'></a>Detecting button presses</h4>
|
||||
<!-- l. 1474 --><p class='noindent'>Many popular single board computers, such as Raspberry Pi or Beagleboards, have a
|
||||
<!-- l. 1476 --><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
|
||||
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. 1478 --><p class='indent'> Here is an example where buttons are connected to GPIO numbers 17 and 18 and
|
||||
</p><!-- l. 1480 --><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'>
|
||||
@ -4452,14 +4452,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='textcolor2290'><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='textcolor2291'><span class='ectt-0800'>"Handle some GPIO interrupts"</span></span><span class='ectt-0800'>);</span></pre>
|
||||
<!-- l. 1483 --><p class='noindent'>
|
||||
<!-- l. 1485 --><p class='noindent'>
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='bottom-half'><span class='titlemark'>0.15.3 </span> <a id='x1-580000.15.3'></a>Bottom Half</h4>
|
||||
<!-- l. 1485 --><p class='noindent'>Suppose you want to do a bunch of stuff inside of an interrupt routine. A common
|
||||
<!-- l. 1487 --><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. 1489 --><p class='indent'> The example below modifies the previous example to also run an additional task
|
||||
</p><!-- l. 1491 --><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'>
|
||||
</p>
|
||||
@ -4624,22 +4624,22 @@ when an interrupt is triggered.
|
||||
<a id='x1-58318r159'></a><span class='ecrm-0500'>159</span>
|
||||
<a id='x1-58320r160'></a><span class='ecrm-0500'>160</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor2412'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span>
|
||||
<a id='x1-58322r161'></a><span class='ecrm-0500'>161</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor2413'><span class='ectt-0800'>"Interrupt with top and bottom half"</span></span><span class='ectt-0800'>);</span></pre>
|
||||
<!-- l. 1493 --><p class='noindent'>
|
||||
<!-- l. 1495 --><p class='noindent'>
|
||||
</p>
|
||||
<h3 class='sectionHead' id='crypto'><span class='titlemark'>0.16 </span> <a id='x1-590000.16'></a>Crypto</h3>
|
||||
<!-- l. 1495 --><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
|
||||
<!-- l. 1497 --><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
|
||||
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. 1500 --><p class='noindent'>
|
||||
</p><!-- l. 1502 --><p class='noindent'>
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='hash-functions'><span class='titlemark'>0.16.1 </span> <a id='x1-600000.16.1'></a>Hash functions</h4>
|
||||
<!-- l. 1503 --><p class='noindent'>Calculating and checking the hashes of things is a common operation. Here is a
|
||||
<!-- l. 1505 --><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>
|
||||
@ -4705,21 +4705,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='textcolor2463'><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='textcolor2464'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
||||
<!-- l. 1508 --><p class='indent'> Make and install the module:
|
||||
<!-- l. 1510 --><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. 1516 --><p class='indent'> And you should see that the hash was calculated for the test string.
|
||||
</p><!-- l. 1518 --><p class='indent'> Finally, remove the test module:
|
||||
<!-- l. 1518 --><p class='indent'> And you should see that the hash was calculated for the test string.
|
||||
</p><!-- l. 1520 --><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. 1524 --><p class='noindent'>
|
||||
<!-- l. 1526 --><p class='noindent'>
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='symmetric-key-encryption'><span class='titlemark'>0.16.2 </span> <a id='x1-610000.16.2'></a>Symmetric key encryption</h4>
|
||||
<!-- l. 1526 --><p class='noindent'>Here is an example of symmetrically encrypting a string using the AES algorithm
|
||||
<!-- l. 1528 --><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'>
|
||||
</p>
|
||||
@ -4920,10 +4920,10 @@ and a password.
|
||||
<a id='x1-61390r195'></a><span class='ecrm-0500'>195</span>
|
||||
<a id='x1-61392r196'></a><span class='ecrm-0500'>196</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor2610'><span class='ectt-0800'>"Symmetric key encryption example"</span></span><span class='ectt-0800'>);</span>
|
||||
<a id='x1-61394r197'></a><span class='ecrm-0500'>197</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor2611'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
||||
<!-- l. 1530 --><p class='noindent'>
|
||||
<!-- l. 1532 --><p class='noindent'>
|
||||
</p>
|
||||
<h3 class='sectionHead' id='standardizing-the-interfaces-the-device-model'><span class='titlemark'>0.17 </span> <a id='x1-620000.17'></a>Standardizing the interfaces: The Device Model</h3>
|
||||
<!-- l. 1532 --><p class='noindent'>Up to this point we have seen all kinds of modules doing all kinds of things, but there
|
||||
<!-- l. 1534 --><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 show below, and you can
|
||||
@ -5033,13 +5033,13 @@ functions.
|
||||
|
||||
|
||||
|
||||
<!-- l. 1538 --><p class='noindent'>
|
||||
</p>
|
||||
<h3 class='sectionHead' id='optimizations'><span class='titlemark'>0.18 </span> <a id='x1-630000.18'></a>Optimizations</h3>
|
||||
<!-- l. 1540 --><p class='noindent'>
|
||||
</p>
|
||||
<h3 class='sectionHead' id='optimizations'><span class='titlemark'>0.18 </span> <a id='x1-630000.18'></a>Optimizations</h3>
|
||||
<!-- l. 1542 --><p class='noindent'>
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='likely-and-unlikely-conditions'><span class='titlemark'>0.18.1 </span> <a id='x1-640000.18.1'></a>Likely and Unlikely conditions</h4>
|
||||
<!-- l. 1542 --><p class='noindent'>Sometimes you might want your code to run as quickly as possible,
|
||||
<!-- l. 1544 --><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 noticible latency. If your code contains boolean conditions and if you
|
||||
know that the conditions are almost always likely to evaluate as either
|
||||
@ -5049,7 +5049,7 @@ know that the conditions are almost always likely to evaluate as either
|
||||
<code> <span class='ectt-1000'>likely</span>
|
||||
</code> and <code> <span class='ectt-1000'>unlikely</span>
|
||||
</code> macros.
|
||||
</p><!-- l. 1546 --><p class='indent'> For example, when allocating memory you are almost always expecting this to
|
||||
</p><!-- l. 1548 --><p class='indent'> For example, when allocating memory you are almost always expecting this to
|
||||
succeed.
|
||||
</p><!-- l. 1 --><p class='indent'>
|
||||
</p>
|
||||
@ -5059,50 +5059,50 @@ succeed.
|
||||
<a id='x1-64018r4'></a><span class='ecrm-0500'>4</span><span class='ectt-0800'> bio = NULL;</span>
|
||||
<a id='x1-64020r5'></a><span class='ecrm-0500'>5</span><span class='ectt-0800'> </span><span id='textcolor2689'><span class='ectt-0800'>goto</span></span><span class='ectt-0800'> out;</span>
|
||||
<a id='x1-64022r6'></a><span class='ecrm-0500'>6</span><span class='ectt-0800'>}</span></pre>
|
||||
<!-- l. 1557 --><p class='indent'> When the <code> <span class='ectt-1000'>unlikely</span>
|
||||
<!-- l. 1559 --><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. 1561 --><p class='noindent'>
|
||||
</p><!-- l. 1563 --><p class='noindent'>
|
||||
</p>
|
||||
<h3 class='sectionHead' id='common-pitfalls'><span class='titlemark'>0.19 </span> <a id='x1-650000.19'></a>Common Pitfalls</h3>
|
||||
<!-- l. 1564 --><p class='noindent'>
|
||||
<!-- l. 1566 --><p class='noindent'>
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='using-standard-libraries'><span class='titlemark'>0.19.1 </span> <a id='x1-660000.19.1'></a>Using standard libraries</h4>
|
||||
<!-- l. 1566 --><p class='noindent'>You can not do that. In a kernel module you can only use kernel functions, which are
|
||||
<!-- l. 1568 --><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. 1569 --><p class='noindent'>
|
||||
</p><!-- l. 1571 --><p class='noindent'>
|
||||
</p>
|
||||
<h4 class='subsectionHead' id='disabling-interrupts'><span class='titlemark'>0.19.2 </span> <a id='x1-670000.19.2'></a>Disabling interrupts</h4>
|
||||
<!-- l. 1571 --><p class='noindent'>You might need to do this for a short time and that is OK, but if you do not enable
|
||||
<!-- l. 1573 --><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. 1573 --><p class='noindent'>
|
||||
</p><!-- l. 1575 --><p class='noindent'>
|
||||
</p>
|
||||
<h3 class='sectionHead' id='where-to-go-from-here'><span class='titlemark'>0.20 </span> <a id='x1-680000.20'></a>Where To Go From Here?</h3>
|
||||
<!-- l. 1575 --><p class='noindent'>For people seriously interested in kernel programming, I recommend <a href='https://kernelnewbies.org'>kernelnewbies.org</a>
|
||||
<!-- l. 1577 --><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. 1578 --><p class='indent'> If you are interested in more examples of short kernel modules then searching on
|
||||
</p><!-- l. 1580 --><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
|
||||
or compromise systems or exfiltrate data and those can be useful for thinking about
|
||||
how to defend systems and learning about existing security mechanisms within the
|
||||
kernel.
|
||||
</p><!-- l. 1581 --><p class='indent'> I hope I have helped you in your quest to become a better programmer, or at
|
||||
</p><!-- l. 1583 --><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. 1584 --><p class='indent'> If you would like to contribute to this guide or notice anything glaringly wrong,
|
||||
</p><!-- l. 1586 --><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. 1586 --><p class='indent'> Happy hacking!
|
||||
</p><!-- l. 1588 --><p class='indent'> Happy hacking!
|
||||
</p>
|
||||
|
||||
</body>
|
||||
|
Loading…
x
Reference in New Issue
Block a user