mirror of
https://github.com/sysprog21/lkmpg.git
synced 2025-02-27 00:03:27 +08:00
deploy: 48cb100473bb6fae52cb58d39192d50c08977463
This commit is contained in:
parent
fe2655942a
commit
735fc5233a
267
index.html
267
index.html
@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
<h2 class='titleHead'>The Linux Kernel Module Programming Guide</h2>
|
<h2 class='titleHead'>The Linux Kernel Module Programming Guide</h2>
|
||||||
<div class='author'><span class='ecrm-1200'>Peter Jay Salzman, Michael Burian, Ori Pomerantz, Bob Mottram, Jim Huang</span></div><br />
|
<div class='author'><span class='ecrm-1200'>Peter Jay Salzman, Michael Burian, Ori Pomerantz, Bob Mottram, Jim Huang</span></div><br />
|
||||||
<div class='date'><span class='ecrm-1200'>August 16, 2021</span></div>
|
<div class='date'><span class='ecrm-1200'>August 17, 2021</span></div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -280,7 +280,7 @@ module.
|
|||||||
<pre class='fancyvrb' id='fancyvrb10'><a id='x1-12008r1'></a><span class='ecrm-0500'>1</span><span id='textcolor3'><span class='ectt-0800'>/*</span></span>
|
<pre class='fancyvrb' id='fancyvrb10'><a id='x1-12008r1'></a><span class='ecrm-0500'>1</span><span id='textcolor3'><span class='ectt-0800'>/*</span></span>
|
||||||
<a id='x1-12010r2'></a><span class='ecrm-0500'>2</span><span id='textcolor4'><span class='ectt-0800'> * hello-1.c - The simplest kernel module.</span></span>
|
<a id='x1-12010r2'></a><span class='ecrm-0500'>2</span><span id='textcolor4'><span class='ectt-0800'> * hello-1.c - The simplest kernel module.</span></span>
|
||||||
<a id='x1-12012r3'></a><span class='ecrm-0500'>3</span><span id='textcolor5'><span class='ectt-0800'> */</span></span>
|
<a id='x1-12012r3'></a><span class='ecrm-0500'>3</span><span id='textcolor5'><span class='ectt-0800'> */</span></span>
|
||||||
<a id='x1-12014r4'></a><span class='ecrm-0500'>4</span><span id='textcolor6'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor7'><span class='ectt-0800'><linux/kernel.h> /* Needed for KERN_INFO */</span></span>
|
<a id='x1-12014r4'></a><span class='ecrm-0500'>4</span><span id='textcolor6'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor7'><span class='ectt-0800'><linux/kernel.h> /* Needed for pr_info() */</span></span>
|
||||||
<a id='x1-12016r5'></a><span class='ecrm-0500'>5</span><span id='textcolor8'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor9'><span class='ectt-0800'><linux/module.h> /* Needed by all modules */</span></span>
|
<a id='x1-12016r5'></a><span class='ecrm-0500'>5</span><span id='textcolor8'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor9'><span class='ectt-0800'><linux/module.h> /* Needed by all modules */</span></span>
|
||||||
<a id='x1-12018r6'></a><span class='ecrm-0500'>6</span>
|
<a id='x1-12018r6'></a><span class='ecrm-0500'>6</span>
|
||||||
<a id='x1-12020r7'></a><span class='ecrm-0500'>7</span><span id='textcolor10'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> init_module(</span><span id='textcolor11'><span class='ectt-0800'>void</span></span><span class='ectt-0800'>)</span>
|
<a id='x1-12020r7'></a><span class='ecrm-0500'>7</span><span id='textcolor10'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> init_module(</span><span id='textcolor11'><span class='ectt-0800'>void</span></span><span class='ectt-0800'>)</span>
|
||||||
@ -425,7 +425,7 @@ technique:
|
|||||||
<a id='x1-13010r3'></a><span class='ecrm-0500'>3</span><span id='textcolor30'><span class='ectt-0800'> * This is preferred over using init_module() and cleanup_module().</span></span>
|
<a id='x1-13010r3'></a><span class='ecrm-0500'>3</span><span id='textcolor30'><span class='ectt-0800'> * This is preferred over using init_module() and cleanup_module().</span></span>
|
||||||
<a id='x1-13012r4'></a><span class='ecrm-0500'>4</span><span id='textcolor31'><span class='ectt-0800'> */</span></span>
|
<a id='x1-13012r4'></a><span class='ecrm-0500'>4</span><span id='textcolor31'><span class='ectt-0800'> */</span></span>
|
||||||
<a id='x1-13014r5'></a><span class='ecrm-0500'>5</span><span id='textcolor32'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor33'><span class='ectt-0800'><linux/init.h> /* Needed for the macros */</span></span>
|
<a id='x1-13014r5'></a><span class='ecrm-0500'>5</span><span id='textcolor32'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor33'><span class='ectt-0800'><linux/init.h> /* Needed for the macros */</span></span>
|
||||||
<a id='x1-13016r6'></a><span class='ecrm-0500'>6</span><span id='textcolor34'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor35'><span class='ectt-0800'><linux/kernel.h> /* Needed for KERN_INFO */</span></span>
|
<a id='x1-13016r6'></a><span class='ecrm-0500'>6</span><span id='textcolor34'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor35'><span class='ectt-0800'><linux/kernel.h> /* Needed for pr_info() */</span></span>
|
||||||
<a id='x1-13018r7'></a><span class='ecrm-0500'>7</span><span id='textcolor36'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor37'><span class='ectt-0800'><linux/module.h> /* Needed by all modules */</span></span>
|
<a id='x1-13018r7'></a><span class='ecrm-0500'>7</span><span id='textcolor36'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor37'><span class='ectt-0800'><linux/module.h> /* Needed by all modules */</span></span>
|
||||||
<a id='x1-13020r8'></a><span class='ecrm-0500'>8</span>
|
<a id='x1-13020r8'></a><span class='ecrm-0500'>8</span>
|
||||||
<a id='x1-13022r9'></a><span class='ecrm-0500'>9</span><span id='textcolor38'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor39'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> __init hello_2_init(</span><span id='textcolor40'><span class='ectt-0800'>void</span></span><span class='ectt-0800'>)</span>
|
<a id='x1-13022r9'></a><span class='ecrm-0500'>9</span><span id='textcolor38'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor39'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> __init hello_2_init(</span><span id='textcolor40'><span class='ectt-0800'>void</span></span><span class='ectt-0800'>)</span>
|
||||||
@ -462,7 +462,7 @@ is as simple as this:
|
|||||||
see, some things get hardwired into the kernel (<span class='obeylines-h'><span class='verb'><span class='ectt-1000'>obj-y</span></span></span>) but where are all those <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>obj-m</span></span></span>
|
see, some things get hardwired into the kernel (<span class='obeylines-h'><span class='verb'><span class='ectt-1000'>obj-y</span></span></span>) but where are all those <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>obj-m</span></span></span>
|
||||||
gone? Those familiar with shell scripts will easily be able to spot them. For those not,
|
gone? Those familiar with shell scripts will easily be able to spot them. For those not,
|
||||||
the <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>obj-$(CONFIG_FOO)</span></span></span> entries you see everywhere expand into <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>obj-y</span></span></span> or <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>obj-m</span></span></span>,
|
the <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>obj-$(CONFIG_FOO)</span></span></span> entries you see everywhere expand into <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>obj-y</span></span></span> or <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>obj-m</span></span></span>,
|
||||||
depending on whether the <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>CONFIG_FOO</span></span></span> variable has been set to y or m. While we are
|
depending on whether the <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>CONFIG_FOO</span></span></span> variable has been set to <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>y</span></span></span> or <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>m</span></span></span>. While we are
|
||||||
at it, those were exactly the kind of variables that you have set in the <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>.config</span></span></span> file in
|
at it, those were exactly the kind of variables that you have set in the <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>.config</span></span></span> file in
|
||||||
the top-level directory of Linux kernel source tree, the last time when you said
|
the top-level directory of Linux kernel source tree, the last time when you said
|
||||||
<code> <span class='ectt-1000'>make menuconfig</span>
|
<code> <span class='ectt-1000'>make menuconfig</span>
|
||||||
@ -494,7 +494,7 @@ memory: 236k freed, this is precisely what the kernel is freeing.
|
|||||||
<a id='x1-14009r2'></a><span class='ecrm-0500'>2</span><span id='textcolor57'><span class='ectt-0800'> * hello-3.c - Illustrating the __init, __initdata and __exit macros.</span></span>
|
<a id='x1-14009r2'></a><span class='ecrm-0500'>2</span><span id='textcolor57'><span class='ectt-0800'> * hello-3.c - Illustrating the __init, __initdata and __exit macros.</span></span>
|
||||||
<a id='x1-14011r3'></a><span class='ecrm-0500'>3</span><span id='textcolor58'><span class='ectt-0800'> */</span></span>
|
<a id='x1-14011r3'></a><span class='ecrm-0500'>3</span><span id='textcolor58'><span class='ectt-0800'> */</span></span>
|
||||||
<a id='x1-14013r4'></a><span class='ecrm-0500'>4</span><span id='textcolor59'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor60'><span class='ectt-0800'><linux/init.h> /* Needed for the macros */</span></span>
|
<a id='x1-14013r4'></a><span class='ecrm-0500'>4</span><span id='textcolor59'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor60'><span class='ectt-0800'><linux/init.h> /* Needed for the macros */</span></span>
|
||||||
<a id='x1-14015r5'></a><span class='ecrm-0500'>5</span><span id='textcolor61'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor62'><span class='ectt-0800'><linux/kernel.h> /* Needed for KERN_INFO */</span></span>
|
<a id='x1-14015r5'></a><span class='ecrm-0500'>5</span><span id='textcolor61'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor62'><span class='ectt-0800'><linux/kernel.h> /* Needed for pr_info() */</span></span>
|
||||||
<a id='x1-14017r6'></a><span class='ecrm-0500'>6</span><span id='textcolor63'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor64'><span class='ectt-0800'><linux/module.h> /* Needed by all modules */</span></span>
|
<a id='x1-14017r6'></a><span class='ecrm-0500'>6</span><span id='textcolor63'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor64'><span class='ectt-0800'><linux/module.h> /* Needed by all modules */</span></span>
|
||||||
<a id='x1-14019r7'></a><span class='ecrm-0500'>7</span>
|
<a id='x1-14019r7'></a><span class='ecrm-0500'>7</span>
|
||||||
<a id='x1-14021r8'></a><span class='ecrm-0500'>8</span><span id='textcolor65'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor66'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> hello3_data __initdata = 3;</span>
|
<a id='x1-14021r8'></a><span class='ecrm-0500'>8</span><span id='textcolor65'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor66'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> hello3_data __initdata = 3;</span>
|
||||||
@ -543,7 +543,7 @@ example.
|
|||||||
<a id='x1-15005r2'></a><span class='ecrm-0500'>2</span><span id='textcolor82'><span class='ectt-0800'> * hello-4.c - Demonstrates module documentation.</span></span>
|
<a id='x1-15005r2'></a><span class='ecrm-0500'>2</span><span id='textcolor82'><span class='ectt-0800'> * hello-4.c - Demonstrates module documentation.</span></span>
|
||||||
<a id='x1-15007r3'></a><span class='ecrm-0500'>3</span><span id='textcolor83'><span class='ectt-0800'> */</span></span>
|
<a id='x1-15007r3'></a><span class='ecrm-0500'>3</span><span id='textcolor83'><span class='ectt-0800'> */</span></span>
|
||||||
<a id='x1-15009r4'></a><span class='ecrm-0500'>4</span><span id='textcolor84'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor85'><span class='ectt-0800'><linux/init.h> /* Needed for the macros */</span></span>
|
<a id='x1-15009r4'></a><span class='ecrm-0500'>4</span><span id='textcolor84'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor85'><span class='ectt-0800'><linux/init.h> /* Needed for the macros */</span></span>
|
||||||
<a id='x1-15011r5'></a><span class='ecrm-0500'>5</span><span id='textcolor86'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor87'><span class='ectt-0800'><linux/kernel.h> /* Needed for KERN_INFO */</span></span>
|
<a id='x1-15011r5'></a><span class='ecrm-0500'>5</span><span id='textcolor86'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor87'><span class='ectt-0800'><linux/kernel.h> /* Needed for pr_info() */</span></span>
|
||||||
<a id='x1-15013r6'></a><span class='ecrm-0500'>6</span><span id='textcolor88'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor89'><span class='ectt-0800'><linux/module.h> /* Needed by all modules */</span></span>
|
<a id='x1-15013r6'></a><span class='ecrm-0500'>6</span><span id='textcolor88'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor89'><span class='ectt-0800'><linux/module.h> /* Needed by all modules */</span></span>
|
||||||
<a id='x1-15015r7'></a><span class='ecrm-0500'>7</span>
|
<a id='x1-15015r7'></a><span class='ecrm-0500'>7</span>
|
||||||
<a id='x1-15017r8'></a><span class='ecrm-0500'>8</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor90'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span>
|
<a id='x1-15017r8'></a><span class='ecrm-0500'>8</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor90'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span>
|
||||||
@ -800,7 +800,7 @@ error as follows:
|
|||||||
insmod: error inserting 'poet_atkm.ko': -1 Invalid module format
|
insmod: error inserting 'poet_atkm.ko': -1 Invalid module format
|
||||||
</pre>
|
</pre>
|
||||||
<!-- l. 489 --><p class='nopar'>
|
<!-- l. 489 --><p class='nopar'>
|
||||||
</p><!-- l. 491 --><p class='indent'> Less cryptical information are logged to the systemd journal:
|
</p><!-- l. 491 --><p class='indent'> Less cryptic information is logged to the systemd journal:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -833,8 +833,8 @@ name: hello_4
|
|||||||
vermagic: 5.4.0-70-generic SMP mod_unload modversions
|
vermagic: 5.4.0-70-generic SMP mod_unload modversions
|
||||||
</pre>
|
</pre>
|
||||||
<!-- l. 513 --><p class='nopar'>
|
<!-- l. 513 --><p class='nopar'>
|
||||||
</p><!-- l. 515 --><p class='indent'> To overcome this problem we could resort to the <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>--force-vermagic</span></span></span>
|
</p><!-- l. 515 --><p class='indent'> To overcome this problem we could resort to the <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>--force-vermagic</span></span></span> option,
|
||||||
option, but this solution is potentially unsafe, and unquestionably inacceptable
|
but this solution is potentially unsafe, and unquestionably unacceptable
|
||||||
in production modules. Consequently, we want to compile our module in
|
in production modules. Consequently, we want to compile our module in
|
||||||
an environment which was identical to the one in which our precompiled
|
an environment which was identical to the one in which our precompiled
|
||||||
kernel was built. How to do this, is the subject of the remainder of this
|
kernel was built. How to do this, is the subject of the remainder of this
|
||||||
@ -847,11 +847,11 @@ tree: <code> <span class='ectt-1000'>cp /boot/config-</span><span id='textcolo
|
|||||||
</code>.
|
</code>.
|
||||||
</p><!-- l. 524 --><p class='indent'> Let’s focus again on the previous error message: a closer look at the version magic
|
</p><!-- l. 524 --><p class='indent'> Let’s focus again on the previous error message: a closer look at the version magic
|
||||||
strings suggests that, even with two configuration files which are exactly the same, a
|
strings suggests that, even with two configuration files which are exactly the same, a
|
||||||
slight difference in the version magic could be possible, and it is sufficient to
|
slight difference in the version magic could be possible, and it is sufficient to prevent
|
||||||
prevent insertion of the module into the kernel. That slight difference, namely
|
insertion of the module into the kernel. That slight difference, namely the
|
||||||
the custom string which appears in the module’s version magic and not in
|
custom string which appears in the module’s version magic and not in the
|
||||||
the kernel’s one, is due to a modification with respect to the original, in
|
kernel’s one, is due to a modification with respect to the original, in the
|
||||||
the makefile that some distribution include. Then, examine your <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>Makefile</span></span></span>,
|
makefile that some distributions include. Then, examine your <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>Makefile</span></span></span>,
|
||||||
and make sure that the specified version information matches exactly the
|
and make sure that the specified version information matches exactly the
|
||||||
one used for your current kernel. For example, you makefile could start as
|
one used for your current kernel. For example, you makefile could start as
|
||||||
follows:
|
follows:
|
||||||
@ -974,7 +974,7 @@ data into strings and write the string data using the low-level system call
|
|||||||
<a id='x1-21026r6'></a><span class='ecrm-0500'>6</span><span class='ectt-0800'> </span><span id='textcolor262'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> 0;</span>
|
<a id='x1-21026r6'></a><span class='ecrm-0500'>6</span><span class='ectt-0800'> </span><span id='textcolor262'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> 0;</span>
|
||||||
<a id='x1-21028r7'></a><span class='ecrm-0500'>7</span><span class='ectt-0800'>}</span></pre>
|
<a id='x1-21028r7'></a><span class='ecrm-0500'>7</span><span class='ectt-0800'>}</span></pre>
|
||||||
<!-- l. 608 --><p class='indent'> with <code> <span class='ectt-1000'>gcc -Wall -o hello hello.c</span>
|
<!-- l. 608 --><p class='indent'> with <code> <span class='ectt-1000'>gcc -Wall -o hello hello.c</span>
|
||||||
</code>. Run the exectable with <code> <span class='ectt-1000'>strace ./hello</span>
|
</code>. Run the executable with <code> <span class='ectt-1000'>strace ./hello</span>
|
||||||
</code>. Are you impressed? Every line you see corresponds to a system call. <a href='https://strace.io/'>strace</a> is a
|
</code>. Are you impressed? Every line you see corresponds to a system call. <a href='https://strace.io/'>strace</a> is a
|
||||||
handy program that gives you details about what system calls a program is
|
handy program that gives you details about what system calls a program is
|
||||||
making, including which call is made, what its arguments are and what it
|
making, including which call is made, what its arguments are and what it
|
||||||
@ -1036,8 +1036,8 @@ symbols.
|
|||||||
entire kernel, so this is definitely an issue. The best way to deal with this is to declare
|
entire kernel, so this is definitely an issue. The best way to deal with this is to declare
|
||||||
all your variables as static and to use a well-defined prefix for your symbols. By
|
all your variables as static and to use a well-defined prefix for your symbols. By
|
||||||
convention, all kernel prefixes are lowercase. If you do not want to declare everything
|
convention, all kernel prefixes are lowercase. If you do not want to declare everything
|
||||||
as static, another option is to declare a symbol table and register it with a kernel. We
|
as static, another option is to declare a symbol table and register it with the kernel.
|
||||||
will get to this later.
|
We will get to this later.
|
||||||
</p><!-- l. 652 --><p class='indent'> The file <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>/proc/kallsyms</span></span></span> holds all the symbols that the kernel knows about and
|
</p><!-- l. 652 --><p class='indent'> The file <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>/proc/kallsyms</span></span></span> holds all the symbols that the kernel knows about and
|
||||||
which are therefore accessible to your modules since they share the kernel’s
|
which are therefore accessible to your modules since they share the kernel’s
|
||||||
codespace.
|
codespace.
|
||||||
@ -1583,7 +1583,7 @@ conditional compilation directives. The way to do this to compare the macro
|
|||||||
information to processes — the <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>/proc</span></span></span> file system. Originally designed to allow easy
|
information to processes — the <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>/proc</span></span></span> file system. Originally designed to allow easy
|
||||||
access to information about processes (hence the name), it is now used by every bit
|
access to information about processes (hence the name), it is now used by every bit
|
||||||
of the kernel which has something interesting to report, such as <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>/proc/modules</span></span></span>
|
of the kernel which has something interesting to report, such as <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>/proc/modules</span></span></span>
|
||||||
which provides the list of modules and <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>/proc/meminfo</span></span></span> which stats memory usage
|
which provides the list of modules and <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>/proc/meminfo</span></span></span> which gathers memory usage
|
||||||
statistics.
|
statistics.
|
||||||
</p><!-- l. 943 --><p class='indent'> The method to use the proc file system is very similar to the one used with device
|
</p><!-- l. 943 --><p class='indent'> The method to use the proc file system is very similar to the one used with device
|
||||||
drivers — a structure is created with all the information needed for the <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>/proc</span></span></span> file,
|
drivers — a structure is created with all the information needed for the <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>/proc</span></span></span> file,
|
||||||
@ -1620,7 +1620,7 @@ function <code> <span class='ectt-1000'>procfile_read</span>
|
|||||||
</code>. The return value is a <code> <span id='textcolor548'><span class='ectt-1000'>struct</span></span><span class='ectt-1000'> proc_dir_entry</span>
|
</code>. The return value is a <code> <span id='textcolor548'><span class='ectt-1000'>struct</span></span><span class='ectt-1000'> proc_dir_entry</span>
|
||||||
</code>, and it will be used to configure the file <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>/proc/helloworld</span></span></span> (for example, the owner
|
</code>, and it will be used to configure the file <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>/proc/helloworld</span></span></span> (for example, the owner
|
||||||
of this file). A null return value means that the creation has failed.
|
of this file). A null return value means that the creation has failed.
|
||||||
</p><!-- l. 959 --><p class='indent'> Each time, everytime the file <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>/proc/helloworld</span></span></span> is read, the function
|
</p><!-- l. 959 --><p class='indent'> Every time the file <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>/proc/helloworld</span></span></span> is read, the function
|
||||||
<code> <span class='ectt-1000'>procfile_read</span>
|
<code> <span class='ectt-1000'>procfile_read</span>
|
||||||
</code> is called. Two parameters of this function are very important: the buffer
|
</code> is called. Two parameters of this function are very important: the buffer
|
||||||
(the second parameter) and the offset (the fourth one). The content of the
|
(the second parameter) and the offset (the fourth one). The content of the
|
||||||
@ -2200,7 +2200,7 @@ the same way as in the previous example.
|
|||||||
<!-- l. 1076 --><p class='indent'> If you want more information, you can read this web page:
|
<!-- l. 1076 --><p class='indent'> If you want more information, you can read this web page:
|
||||||
</p>
|
</p>
|
||||||
<ul class='itemize1'>
|
<ul class='itemize1'>
|
||||||
<li class='itemize'><a class='url' href='http://lwn.net/Articles/22355/'><span class='ectt-1000'>http://lwn.net/Articles/22355/</span></a>
|
<li class='itemize'><a class='url' href='https://lwn.net/Articles/22355/'><span class='ectt-1000'>https://lwn.net/Articles/22355/</span></a>
|
||||||
</li>
|
</li>
|
||||||
<li class='itemize'><a class='url' href='https://kernelnewbies.org/Documents/SeqFileHowTo'><span class='ectt-1000'>https://kernelnewbies.org/Documents/SeqFileHowTo</span></a></li></ul>
|
<li class='itemize'><a class='url' href='https://kernelnewbies.org/Documents/SeqFileHowTo'><span class='ectt-1000'>https://kernelnewbies.org/Documents/SeqFileHowTo</span></a></li></ul>
|
||||||
<!-- l. 1083 --><p class='indent'> You can also read the code of <a href='https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/fs/seq_file.c'>fs/seq_file.c</a> in the linux kernel.
|
<!-- l. 1083 --><p class='indent'> You can also read the code of <a href='https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/fs/seq_file.c'>fs/seq_file.c</a> in the linux kernel.
|
||||||
@ -2327,7 +2327,7 @@ device file to write things to the modem (either modem commands or data to
|
|||||||
be sent through the phone line) and read things from the modem (either
|
be sent through the phone line) and read things from the modem (either
|
||||||
responses for commands or the data received through the phone line). However,
|
responses for commands or the data received through the phone line). However,
|
||||||
this leaves open the question of what to do when you need to talk to the
|
this leaves open the question of what to do when you need to talk to the
|
||||||
serial port itself, for example to send the rate at which data is sent and
|
serial port itself, for example to configure the rate at which data is sent and
|
||||||
received.
|
received.
|
||||||
|
|
||||||
|
|
||||||
@ -2360,7 +2360,7 @@ ioctl.c.
|
|||||||
</p><!-- l. 1155 --><p class='indent'> If you want to use ioctls in your own kernel modules, it is best to receive an
|
</p><!-- l. 1155 --><p class='indent'> If you want to use ioctls in your own kernel modules, it is best to receive an
|
||||||
official ioctl assignment, so if you accidentally get somebody else’s ioctls, or if they
|
official ioctl assignment, so if you accidentally get somebody else’s ioctls, or if they
|
||||||
get yours, you’ll know something is wrong. For more information, consult the kernel
|
get yours, you’ll know something is wrong. For more information, consult the kernel
|
||||||
source tree at <a href='https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/Documentation/driver-api/ioctl.rst'>Documentation/driver-api/ioctl.rst</a>.
|
source tree at <a href='https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/Documentation/userspace-api/ioctl/ioctl-number.rst'>Documentation/userspace-api/ioctl/ioctl-number.rst</a>.
|
||||||
</p><!-- l. 1 --><p class='indent'>
|
</p><!-- l. 1 --><p class='indent'>
|
||||||
</p>
|
</p>
|
||||||
<pre class='fancyvrb' id='fancyvrb49'><a id='x1-39009r1'></a><span class='ecrm-0500'>1</span><span id='textcolor964'><span class='ectt-0800'>/*</span></span>
|
<pre class='fancyvrb' id='fancyvrb49'><a id='x1-39009r1'></a><span class='ecrm-0500'>1</span><span id='textcolor964'><span class='ectt-0800'>/*</span></span>
|
||||||
@ -2843,30 +2843,30 @@ source tree at <a href='https://git.kernel.org/pub/scm/linux/kernel/git/stable/l
|
|||||||
<a id='x1-39951r196'></a><span class='ecrm-0500'>196</span>
|
<a id='x1-39951r196'></a><span class='ecrm-0500'>196</span>
|
||||||
<a id='x1-39953r197'></a><span class='ecrm-0500'>197</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor1336'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span>
|
<a id='x1-39953r197'></a><span class='ecrm-0500'>197</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor1336'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span>
|
||||||
<a id='x1-39955r198'></a><span class='ecrm-0500'>198</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor1337'><span class='ectt-0800'>"This is test_ioctl module"</span></span><span class='ectt-0800'>);</span></pre>
|
<a id='x1-39955r198'></a><span class='ecrm-0500'>198</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor1337'><span class='ectt-0800'>"This is test_ioctl module"</span></span><span class='ectt-0800'>);</span></pre>
|
||||||
<!-- l. 1165 --><p class='noindent'>
|
<!-- l. 1164 --><p class='noindent'>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<h3 class='sectionHead' id='system-calls'><span class='titlemark'>0.10 </span> <a id='x1-400000.10'></a>System Calls</h3>
|
<h3 class='sectionHead' id='system-calls'><span class='titlemark'>0.10 </span> <a id='x1-400000.10'></a>System Calls</h3>
|
||||||
<!-- l. 1167 --><p class='noindent'>So far, the only thing we’ve done was to use well defined kernel mechanisms to
|
<!-- l. 1166 --><p class='noindent'>So far, the only thing we’ve done was to use well defined kernel mechanisms to
|
||||||
register <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>/proc</span></span></span> files and device handlers. This is fine if you want to do something the
|
register <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>/proc</span></span></span> files and device handlers. This is fine if you want to do something the
|
||||||
kernel programmers thought you’d want, such as write a device driver. But what if
|
kernel programmers thought you’d want, such as write a device driver. But what if
|
||||||
you want to do something unusual, to change the behavior of the system in some
|
you want to do something unusual, to change the behavior of the system in some
|
||||||
way? Then, you are mostly on your own.
|
way? Then, you are mostly on your own.
|
||||||
</p><!-- l. 1172 --><p class='indent'> If you are not being sensible and using a virtual machine then this is where kernel
|
</p><!-- l. 1171 --><p class='indent'> If you are not being sensible and using a virtual machine then this is where kernel
|
||||||
programming can become hazardous. While writing the example below, I killed the
|
programming can become hazardous. While writing the example below, I killed the
|
||||||
<code> <span class='ectt-1000'>open()</span>
|
<code> <span class='ectt-1000'>open()</span>
|
||||||
</code> system call. This meant I could not open any files, I could not run any
|
</code> system call. This meant I could not open any files, I could not run any
|
||||||
programs, and I could not shutdown the system. I had to restart the virtual
|
programs, and I could not shutdown the system. I had to restart the virtual
|
||||||
machine. No important files got anihilated, but if I was doing this on some live
|
machine. No important files got annihilated, but if I was doing this on some live
|
||||||
mission critical system then that could have been a possible outcome. To
|
mission critical system then that could have been a possible outcome. To
|
||||||
ensure you do not lose any files, even within a test environment, please run
|
ensure you do not lose any files, even within a test environment, please run
|
||||||
<code> <span class='ectt-1000'>sync</span>
|
<code> <span class='ectt-1000'>sync</span>
|
||||||
</code> right before you do the <code> <span class='ectt-1000'>insmod</span>
|
</code> right before you do the <code> <span class='ectt-1000'>insmod</span>
|
||||||
</code> and the <code> <span class='ectt-1000'>rmmod</span>
|
</code> and the <code> <span class='ectt-1000'>rmmod</span>
|
||||||
</code>.
|
</code>.
|
||||||
</p><!-- l. 1179 --><p class='indent'> Forget about <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>/proc</span></span></span> files, forget about device files. They are just minor details.
|
</p><!-- l. 1178 --><p class='indent'> Forget about <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>/proc</span></span></span> files, forget about device files. They are just minor details.
|
||||||
Minutiae in the vast expanse of the universe. The real process to kernel
|
Minutiae in the vast expanse of the universe. The real process to kernel
|
||||||
communication mechanism, the one used by all processes, is <span class='ecti-1000'>system calls</span>. When a
|
communication mechanism, the one used by all processes, is <span class='ecti-1000'>system calls</span>. When a
|
||||||
process requests a service from the kernel (such as opening a file, forking to a new
|
process requests a service from the kernel (such as opening a file, forking to a new
|
||||||
@ -2875,11 +2875,11 @@ change the behaviour of the kernel in interesting ways, this is the place to do
|
|||||||
it. By the way, if you want to see which system calls a program uses, run
|
it. By the way, if you want to see which system calls a program uses, run
|
||||||
<code> <span class='ectt-1000'>strace <arguments></span>
|
<code> <span class='ectt-1000'>strace <arguments></span>
|
||||||
</code>.
|
</code>.
|
||||||
</p><!-- l. 1187 --><p class='indent'> In general, a process is not supposed to be able to access the kernel. It can not
|
</p><!-- l. 1186 --><p class='indent'> In general, a process is not supposed to be able to access the kernel. It can not
|
||||||
access kernel memory and it can’t call kernel functions. The hardware of the CPU
|
access kernel memory and it can’t call kernel functions. The hardware of the CPU
|
||||||
enforces this (that is the reason why it is called “protected mode” or “page
|
enforces this (that is the reason why it is called “protected mode” or “page
|
||||||
protection”).
|
protection”).
|
||||||
</p><!-- l. 1191 --><p class='indent'> System calls are an exception to this general rule. What happens is that the
|
</p><!-- l. 1190 --><p class='indent'> System calls are an exception to this general rule. What happens is that the
|
||||||
process fills the registers with the appropriate values and then calls a special
|
process fills the registers with the appropriate values and then calls a special
|
||||||
instruction which jumps to a previously defined location in the kernel (of course, that
|
instruction which jumps to a previously defined location in the kernel (of course, that
|
||||||
location is readable by user processes, it is not writable by them). Under Intel CPUs,
|
location is readable by user processes, it is not writable by them). Under Intel CPUs,
|
||||||
@ -2887,7 +2887,7 @@ this is done by means of interrupt 0x80. The hardware knows that once you jump t
|
|||||||
this location, you are no longer running in restricted user mode, but as the
|
this location, you are no longer running in restricted user mode, but as the
|
||||||
operating system kernel — and therefore you’re allowed to do whatever you
|
operating system kernel — and therefore you’re allowed to do whatever you
|
||||||
want.
|
want.
|
||||||
</p><!-- l. 1196 --><p class='indent'> The location in the kernel a process can jump to is called <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>system_call</span></span></span>. The
|
</p><!-- l. 1195 --><p class='indent'> The location in the kernel a process can jump to is called <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>system_call</span></span></span>. The
|
||||||
procedure at that location checks the system call number, which tells the kernel what
|
procedure at that location checks the system call number, which tells the kernel what
|
||||||
service the process requested. Then, it looks at the table of system calls
|
service the process requested. Then, it looks at the table of system calls
|
||||||
(<code> <span class='ectt-1000'>sys_call_table</span>
|
(<code> <span class='ectt-1000'>sys_call_table</span>
|
||||||
@ -2900,7 +2900,7 @@ different process, if the process time ran out). If you want to read this code,
|
|||||||
at the source file <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>arch/$(architecture)/kernel/entry.S</span></span></span>, after the line
|
at the source file <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>arch/$(architecture)/kernel/entry.S</span></span></span>, after the line
|
||||||
<code> <span class='ectt-1000'>ENTRY(system_call)</span>
|
<code> <span class='ectt-1000'>ENTRY(system_call)</span>
|
||||||
</code>.
|
</code>.
|
||||||
</p><!-- l. 1202 --><p class='indent'> So, if we want to change the way a certain system call works, what we need to do
|
</p><!-- l. 1201 --><p class='indent'> So, if we want to change the way a certain system call works, what we need to do
|
||||||
is to write our own function to implement it (usually by adding a bit of our own
|
is to write our own function to implement it (usually by adding a bit of our own
|
||||||
code, and then calling the original function) and then change the pointer at
|
code, and then calling the original function) and then change the pointer at
|
||||||
<code> <span class='ectt-1000'>sys_call_table</span>
|
<code> <span class='ectt-1000'>sys_call_table</span>
|
||||||
@ -2908,7 +2908,7 @@ code, and then calling the original function) and then change the pointer at
|
|||||||
don’t want to leave the system in an unstable state, it’s important for
|
don’t want to leave the system in an unstable state, it’s important for
|
||||||
<code> <span class='ectt-1000'>cleanup_module</span>
|
<code> <span class='ectt-1000'>cleanup_module</span>
|
||||||
</code> to restore the table to its original state.
|
</code> to restore the table to its original state.
|
||||||
</p><!-- l. 1205 --><p class='indent'> The source code here is an example of such a kernel module. We want to “spy” on a certain
|
</p><!-- l. 1204 --><p class='indent'> The source code here is an example of such a kernel module. We want to “spy” on a certain
|
||||||
user, and to <code> <span class='ectt-1000'>pr_info()</span>
|
user, and to <code> <span class='ectt-1000'>pr_info()</span>
|
||||||
</code> a message whenever that user opens a file. Towards this end, we
|
</code> a message whenever that user opens a file. Towards this end, we
|
||||||
replace the system call to open a file with our own function, called
|
replace the system call to open a file with our own function, called
|
||||||
@ -2918,7 +2918,7 @@ spy on, it calls <code> <span class='ectt-1000'>pr_info()</span>
|
|||||||
</code> to display the name of the file to be opened. Then, either way, it calls the original
|
</code> to display the name of the file to be opened. Then, either way, it calls the original
|
||||||
<code> <span class='ectt-1000'>open()</span>
|
<code> <span class='ectt-1000'>open()</span>
|
||||||
</code> function with the same parameters, to actually open the file.
|
</code> function with the same parameters, to actually open the file.
|
||||||
</p><!-- l. 1211 --><p class='indent'> The <code> <span class='ectt-1000'>init_module</span>
|
</p><!-- l. 1210 --><p class='indent'> The <code> <span class='ectt-1000'>init_module</span>
|
||||||
</code> function replaces the appropriate location in
|
</code> function replaces the appropriate location in
|
||||||
<code> <span class='ectt-1000'>sys_call_table</span>
|
<code> <span class='ectt-1000'>sys_call_table</span>
|
||||||
</code> and keeps the original pointer in a variable. The
|
</code> and keeps the original pointer in a variable. The
|
||||||
@ -2936,7 +2936,7 @@ with <code> <span class='ectt-1000'>B_open</span>
|
|||||||
</code>, which will call what it thinks is the original system call,
|
</code>, which will call what it thinks is the original system call,
|
||||||
<code> <span class='ectt-1000'>A_open</span>
|
<code> <span class='ectt-1000'>A_open</span>
|
||||||
</code>, when it’s done.
|
</code>, when it’s done.
|
||||||
</p><!-- l. 1218 --><p class='indent'> Now, if B is removed first, everything will be well — it will simply restore the system
|
</p><!-- l. 1217 --><p class='indent'> Now, if B is removed first, everything will be well — it will simply restore the system
|
||||||
call to <code> <span class='ectt-1000'>A_open</span>
|
call to <code> <span class='ectt-1000'>A_open</span>
|
||||||
</code>, which calls the original. However, if A is removed and then B is removed, the
|
</code>, which calls the original. However, if A is removed and then B is removed, the
|
||||||
system will crash. A’s removal will restore the system call to the original,
|
system will crash. A’s removal will restore the system call to the original,
|
||||||
@ -2959,7 +2959,7 @@ problem. When A is removed, it sees that the system call was changed to
|
|||||||
</code> will still try to call <code> <span class='ectt-1000'>A_open</span>
|
</code> will still try to call <code> <span class='ectt-1000'>A_open</span>
|
||||||
</code> which is no longer there, so that even without removing B the system would
|
</code> which is no longer there, so that even without removing B the system would
|
||||||
crash.
|
crash.
|
||||||
</p><!-- l. 1226 --><p class='indent'> Note that all the related problems make syscall stealing unfeasiable for
|
</p><!-- l. 1225 --><p class='indent'> Note that all the related problems make syscall stealing unfeasible for
|
||||||
production use. In order to keep people from doing potential harmful things
|
production use. In order to keep people from doing potential harmful things
|
||||||
<code> <span class='ectt-1000'>sys_call_table</span>
|
<code> <span class='ectt-1000'>sys_call_table</span>
|
||||||
</code> is no longer exported. This means, if you want to do something more than a mere
|
</code> is no longer exported. This means, if you want to do something more than a mere
|
||||||
@ -2967,8 +2967,8 @@ dry run of this example, you will have to patch your current kernel in order to
|
|||||||
<code> <span class='ectt-1000'>sys_call_table</span>
|
<code> <span class='ectt-1000'>sys_call_table</span>
|
||||||
</code> exported. In the example directory you will find a README and the patch. As you
|
</code> exported. In the example directory you will find a README and the patch. As you
|
||||||
can imagine, such modifications are not to be taken lightly. Do not try this on
|
can imagine, such modifications are not to be taken lightly. Do not try this on
|
||||||
valueable systems (ie systems that you do not own - or cannot restore easily). You
|
valuable systems (ie systems that you do not own - or cannot restore easily). You will
|
||||||
will need to get the complete sourcecode of this guide as a tarball in order to get the
|
need to get the complete sourcecode of this guide as a tarball in order to get the
|
||||||
patch and the README. Depending on your kernel version, you might even need to
|
patch and the README. Depending on your kernel version, you might even need to
|
||||||
hand apply the patch.
|
hand apply the patch.
|
||||||
</p><!-- l. 1 --><p class='indent'>
|
</p><!-- l. 1 --><p class='indent'>
|
||||||
@ -3110,13 +3110,13 @@ hand apply the patch.
|
|||||||
<a id='x1-40302r135'></a><span class='ecrm-0500'>135</span><span class='ectt-0800'>module_exit(syscall_end);</span>
|
<a id='x1-40302r135'></a><span class='ecrm-0500'>135</span><span class='ectt-0800'>module_exit(syscall_end);</span>
|
||||||
<a id='x1-40304r136'></a><span class='ecrm-0500'>136</span>
|
<a id='x1-40304r136'></a><span class='ecrm-0500'>136</span>
|
||||||
<a id='x1-40306r137'></a><span class='ecrm-0500'>137</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor1471'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
<a id='x1-40306r137'></a><span class='ecrm-0500'>137</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor1471'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
||||||
<!-- l. 1237 --><p class='noindent'>
|
<!-- l. 1236 --><p class='noindent'>
|
||||||
</p>
|
</p>
|
||||||
<h3 class='sectionHead' id='blocking-processes-and-threads'><span class='titlemark'>0.11 </span> <a id='x1-410000.11'></a>Blocking Processes and threads</h3>
|
<h3 class='sectionHead' id='blocking-processes-and-threads'><span class='titlemark'>0.11 </span> <a id='x1-410000.11'></a>Blocking Processes and threads</h3>
|
||||||
<!-- l. 1239 --><p class='noindent'>
|
<!-- l. 1238 --><p class='noindent'>
|
||||||
</p>
|
</p>
|
||||||
<h4 class='subsectionHead' id='sleep'><span class='titlemark'>0.11.1 </span> <a id='x1-420000.11.1'></a>Sleep</h4>
|
<h4 class='subsectionHead' id='sleep'><span class='titlemark'>0.11.1 </span> <a id='x1-420000.11.1'></a>Sleep</h4>
|
||||||
<!-- l. 1241 --><p class='noindent'>What do you do when somebody asks you for something you can not do right
|
<!-- l. 1240 --><p class='noindent'>What do you do when somebody asks you for something you can not do right
|
||||||
away? If you are a human being and you are bothered by a human being, the
|
away? If you are a human being and you are bothered by a human being, the
|
||||||
only thing you can say is: "<span class='ecti-1000'>Not right now, I’m busy. Go away!</span>". But if you
|
only thing you can say is: "<span class='ecti-1000'>Not right now, I’m busy. Go away!</span>". But if you
|
||||||
are a kernel module and you are bothered by a process, you have another
|
are a kernel module and you are bothered by a process, you have another
|
||||||
@ -3127,21 +3127,21 @@ processes are being put to sleep by the kernel and woken up all the time (that
|
|||||||
|
|
||||||
is the way multiple processes appear to run on the same time on a single
|
is the way multiple processes appear to run on the same time on a single
|
||||||
CPU).
|
CPU).
|
||||||
</p><!-- l. 1247 --><p class='indent'> This kernel module is an example of this. The file (called <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>/proc/sleep</span></span></span>) can only
|
</p><!-- l. 1246 --><p class='indent'> This kernel module is an example of this. The file (called <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>/proc/sleep</span></span></span>) can only
|
||||||
be opened by a single process at a time. If the file is already open, the kernel module
|
be opened by a single process at a time. If the file is already open, the kernel module
|
||||||
calls <code> <span class='ectt-1000'>wait_event_interruptible</span>
|
calls <code> <span class='ectt-1000'>wait_event_interruptible</span>
|
||||||
</code>. The easiest way to keep a file open is to open it with:
|
</code>. The easiest way to keep a file open is to open it with:
|
||||||
</p><!-- l. 1 --><p class='indent'>
|
</p><!-- l. 1 --><p class='indent'>
|
||||||
</p>
|
</p>
|
||||||
<pre class='fancyvrb' id='fancyvrb53'><a id='x1-42004r1'></a><span class='ecrm-0500'>1</span><span class='ectt-1000'>tail -f</span></pre>
|
<pre class='fancyvrb' id='fancyvrb53'><a id='x1-42004r1'></a><span class='ecrm-0500'>1</span><span class='ectt-1000'>tail -f</span></pre>
|
||||||
<!-- l. 1256 --><p class='indent'> This function changes the status of the task (a task is the kernel data structure
|
<!-- l. 1255 --><p class='indent'> This function changes the status of the task (a task is the kernel data structure
|
||||||
which holds information about a process and the system call it is in, if any) to
|
which holds information about a process and the system call it is in, if any) to
|
||||||
<code> <span class='ectt-1000'>TASK_INTERRUPTIBLE</span>
|
<code> <span class='ectt-1000'>TASK_INTERRUPTIBLE</span>
|
||||||
</code>, which means that the task will not run until it is woken up somehow, and adds it to
|
</code>, which means that the task will not run until it is woken up somehow, and adds it to
|
||||||
WaitQ, the queue of tasks waiting to access the file. Then, the function calls the
|
WaitQ, the queue of tasks waiting to access the file. Then, the function calls the
|
||||||
scheduler to context switch to a different process, one which has some use for the
|
scheduler to context switch to a different process, one which has some use for the
|
||||||
CPU.
|
CPU.
|
||||||
</p><!-- l. 1260 --><p class='indent'> When a process is done with the file, it closes it, and
|
</p><!-- l. 1259 --><p class='indent'> When a process is done with the file, it closes it, and
|
||||||
<code> <span class='ectt-1000'>module_close</span>
|
<code> <span class='ectt-1000'>module_close</span>
|
||||||
</code> is called. That function wakes up all the processes in the queue (there’s no
|
</code> is called. That function wakes up all the processes in the queue (there’s no
|
||||||
mechanism to only wake up one of them). It then returns and the process which just
|
mechanism to only wake up one of them). It then returns and the process which just
|
||||||
@ -3151,20 +3151,20 @@ Eventually, one of the processes which was in the queue will be given control
|
|||||||
of the CPU by the scheduler. It starts at the point right after the call to
|
of the CPU by the scheduler. It starts at the point right after the call to
|
||||||
<code> <span class='ectt-1000'>module_interruptible_sleep_on</span>
|
<code> <span class='ectt-1000'>module_interruptible_sleep_on</span>
|
||||||
</code>.
|
</code>.
|
||||||
</p><!-- l. 1267 --><p class='indent'> This means that the process is still in kernel mode - as far as the process
|
</p><!-- l. 1266 --><p class='indent'> This means that the process is still in kernel mode - as far as the process
|
||||||
is concerned, it issued the open system call and the system call has not
|
is concerned, it issued the open system call and the system call has not
|
||||||
returned yet. The process does not know somebody else used the CPU for
|
returned yet. The process does not know somebody else used the CPU for
|
||||||
most of the time between the moment it issued the call and the moment it
|
most of the time between the moment it issued the call and the moment it
|
||||||
returned.
|
returned.
|
||||||
</p><!-- l. 1270 --><p class='indent'> It can then proceed to set a global variable to tell all the other processes that the
|
</p><!-- l. 1269 --><p class='indent'> It can then proceed to set a global variable to tell all the other processes that the
|
||||||
file is still open and go on with its life. When the other processes get a piece of the
|
file is still open and go on with its life. When the other processes get a piece of the
|
||||||
CPU, they’ll see that global variable and go back to sleep.
|
CPU, they’ll see that global variable and go back to sleep.
|
||||||
</p><!-- l. 1273 --><p class='indent'> So we will use <code> <span class='ectt-1000'>tail -f</span>
|
</p><!-- l. 1272 --><p class='indent'> So we will use <code> <span class='ectt-1000'>tail -f</span>
|
||||||
</code> to keep the file open in the background, while trying to access it with another
|
</code> to keep the file open in the background, while trying to access it with another
|
||||||
process (again in the background, so that we need not switch to a different vt). As
|
process (again in the background, so that we need not switch to a different vt). As
|
||||||
soon as the first background process is killed with kill %1 , the second is woken up, is
|
soon as the first background process is killed with kill %1 , the second is woken up, is
|
||||||
able to access the file and finally terminates.
|
able to access the file and finally terminates.
|
||||||
</p><!-- l. 1276 --><p class='indent'> To make our life more interesting, <code> <span class='ectt-1000'>module_close</span>
|
</p><!-- l. 1275 --><p class='indent'> To make our life more interesting, <code> <span class='ectt-1000'>module_close</span>
|
||||||
</code> does not have a monopoly on waking up the processes which wait to access the file.
|
</code> does not have a monopoly on waking up the processes which wait to access the file.
|
||||||
A signal, such as <span class='ecti-1000'>Ctrl +c </span>(<span class='ecbx-1000'>SIGINT</span>) can also wake up a process. This is because we
|
A signal, such as <span class='ecti-1000'>Ctrl +c </span>(<span class='ecbx-1000'>SIGINT</span>) can also wake up a process. This is because we
|
||||||
used <code> <span class='ectt-1000'>module_interruptible_sleep_on</span>
|
used <code> <span class='ectt-1000'>module_interruptible_sleep_on</span>
|
||||||
@ -3174,11 +3174,11 @@ used <code> <span class='ectt-1000'>module_interruptible_sleep_on</span>
|
|||||||
|
|
||||||
</code> instead, but that would have resulted in extremely angry users whose <span class='ecti-1000'>Ctrl+c</span>’s are
|
</code> instead, but that would have resulted in extremely angry users whose <span class='ecti-1000'>Ctrl+c</span>’s are
|
||||||
ignored.
|
ignored.
|
||||||
</p><!-- l. 1280 --><p class='indent'> In that case, we want to return with
|
</p><!-- l. 1279 --><p class='indent'> In that case, we want to return with
|
||||||
<code> <span class='ectt-1000'>-EINTR</span>
|
<code> <span class='ectt-1000'>-EINTR</span>
|
||||||
</code> immediately. This is important so users can, for example, kill the process before it
|
</code> immediately. This is important so users can, for example, kill the process before it
|
||||||
receives the file.
|
receives the file.
|
||||||
</p><!-- l. 1282 --><p class='indent'> There is one more point to remember. Some times processes don’t want to sleep, they want
|
</p><!-- l. 1281 --><p class='indent'> There is one more point to remember. Some times processes don’t want to sleep, they want
|
||||||
either to get what they want immediately, or to be told it cannot be done. Such processes
|
either to get what they want immediately, or to be told it cannot be done. Such processes
|
||||||
use the <code> <span class='ectt-1000'>O_NONBLOCK</span>
|
use the <code> <span class='ectt-1000'>O_NONBLOCK</span>
|
||||||
</code> flag when opening the file. The kernel is supposed to respond by returning with the error
|
</code> flag when opening the file. The kernel is supposed to respond by returning with the error
|
||||||
@ -3214,7 +3214,7 @@ $ cat_nonblock /proc/sleep
|
|||||||
Last input:
|
Last input:
|
||||||
$
|
$
|
||||||
</pre>
|
</pre>
|
||||||
<!-- l. 1307 --><p class='nopar'>
|
<!-- l. 1306 --><p class='nopar'>
|
||||||
</p><!-- l. 1 --><p class='indent'>
|
</p><!-- l. 1 --><p class='indent'>
|
||||||
</p>
|
</p>
|
||||||
<pre class='fancyvrb' id='fancyvrb54'><a id='x1-42018r1'></a><span class='ecrm-0500'>1</span><span id='textcolor1472'><span class='ectt-0800'>/*</span></span>
|
<pre class='fancyvrb' id='fancyvrb54'><a id='x1-42018r1'></a><span class='ecrm-0500'>1</span><span id='textcolor1472'><span class='ectt-0800'>/*</span></span>
|
||||||
@ -3498,14 +3498,14 @@ $
|
|||||||
<a id='x1-42568r57'></a><span class='ecrm-0500'>57</span>
|
<a id='x1-42568r57'></a><span class='ecrm-0500'>57</span>
|
||||||
<a id='x1-42570r58'></a><span class='ecrm-0500'>58</span><span class='ectt-0800'> </span><span id='textcolor1709'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> 0;</span>
|
<a id='x1-42570r58'></a><span class='ecrm-0500'>58</span><span class='ectt-0800'> </span><span id='textcolor1709'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> 0;</span>
|
||||||
<a id='x1-42572r59'></a><span class='ecrm-0500'>59</span><span class='ectt-0800'>}</span></pre>
|
<a id='x1-42572r59'></a><span class='ecrm-0500'>59</span><span class='ectt-0800'>}</span></pre>
|
||||||
<!-- l. 1313 --><p class='noindent'>
|
<!-- l. 1312 --><p class='noindent'>
|
||||||
</p>
|
</p>
|
||||||
<h4 class='subsectionHead' id='completions'><span class='titlemark'>0.11.2 </span> <a id='x1-430000.11.2'></a>Completions</h4>
|
<h4 class='subsectionHead' id='completions'><span class='titlemark'>0.11.2 </span> <a id='x1-430000.11.2'></a>Completions</h4>
|
||||||
<!-- l. 1315 --><p class='noindent'>Sometimes one thing should happen before another within a module having multiple threads.
|
<!-- l. 1314 --><p class='noindent'>Sometimes one thing should happen before another within a module having multiple threads.
|
||||||
Rather than using <code> <span class='ectt-1000'>/bin/sleep</span>
|
Rather than using <code> <span class='ectt-1000'>/bin/sleep</span>
|
||||||
</code> commands, the kernel has another way to do this which allows timeouts or
|
</code> commands, the kernel has another way to do this which allows timeouts or
|
||||||
interrupts to also happen.
|
interrupts to also happen.
|
||||||
</p><!-- l. 1318 --><p class='indent'> In the following example two threads are started, but one needs to start before
|
</p><!-- l. 1317 --><p class='indent'> In the following example two threads are started, but one needs to start before
|
||||||
another.
|
another.
|
||||||
</p><!-- l. 1 --><p class='indent'>
|
</p><!-- l. 1 --><p class='indent'>
|
||||||
|
|
||||||
@ -3588,31 +3588,31 @@ another.
|
|||||||
<a id='x1-43149r74'></a><span class='ecrm-0500'>74</span>
|
<a id='x1-43149r74'></a><span class='ecrm-0500'>74</span>
|
||||||
<a id='x1-43151r75'></a><span class='ecrm-0500'>75</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor1760'><span class='ectt-0800'>"Completions example"</span></span><span class='ectt-0800'>);</span>
|
<a id='x1-43151r75'></a><span class='ecrm-0500'>75</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor1760'><span class='ectt-0800'>"Completions example"</span></span><span class='ectt-0800'>);</span>
|
||||||
<a id='x1-43153r76'></a><span class='ecrm-0500'>76</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor1761'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
<a id='x1-43153r76'></a><span class='ecrm-0500'>76</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor1761'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
||||||
<!-- l. 1322 --><p class='indent'> The <code> <span class='ectt-1000'>machine</span>
|
<!-- l. 1321 --><p class='indent'> The <code> <span class='ectt-1000'>machine</span>
|
||||||
</code> structure stores the completion states for the two threads. At the exit
|
</code> structure stores the completion states for the two threads. At the exit
|
||||||
point of each thread the respective completion state is updated, and
|
point of each thread the respective completion state is updated, and
|
||||||
<code> <span class='ectt-1000'>wait_for_completion</span>
|
<code> <span class='ectt-1000'>wait_for_completion</span>
|
||||||
</code> is used by the flywheel thread to ensure that it does not begin prematurely.
|
</code> is used by the flywheel thread to ensure that it does not begin prematurely.
|
||||||
</p><!-- l. 1325 --><p class='indent'> So even though <code> <span class='ectt-1000'>flywheel_thread</span>
|
</p><!-- l. 1324 --><p class='indent'> So even though <code> <span class='ectt-1000'>flywheel_thread</span>
|
||||||
</code> is started first you should notice if you load this module and run
|
</code> is started first you should notice if you load this module and run
|
||||||
<code> <span class='ectt-1000'>dmesg</span>
|
<code> <span class='ectt-1000'>dmesg</span>
|
||||||
</code> that turning the crank always happens first because the flywheel thread waits for it
|
</code> that turning the crank always happens first because the flywheel thread waits for it
|
||||||
to complete.
|
to complete.
|
||||||
</p><!-- l. 1327 --><p class='indent'> There are other variations upon the
|
</p><!-- l. 1326 --><p class='indent'> There are other variations upon the
|
||||||
<code> <span class='ectt-1000'>wait_for_completion</span>
|
<code> <span class='ectt-1000'>wait_for_completion</span>
|
||||||
</code> function, which include timeouts or being interrupted, but this basic mechanism is
|
</code> function, which include timeouts or being interrupted, but this basic mechanism is
|
||||||
enough for many common situations without adding a lot of complexity.
|
enough for many common situations without adding a lot of complexity.
|
||||||
</p><!-- l. 1329 --><p class='noindent'>
|
</p><!-- l. 1328 --><p class='noindent'>
|
||||||
</p>
|
</p>
|
||||||
<h3 class='sectionHead' id='avoiding-collisions-and-deadlocks'><span class='titlemark'>0.12 </span> <a id='x1-440000.12'></a>Avoiding Collisions and Deadlocks</h3>
|
<h3 class='sectionHead' id='avoiding-collisions-and-deadlocks'><span class='titlemark'>0.12 </span> <a id='x1-440000.12'></a>Avoiding Collisions and Deadlocks</h3>
|
||||||
<!-- l. 1331 --><p class='noindent'>If processes running on different CPUs or in different threads try to access the same
|
<!-- l. 1330 --><p class='noindent'>If processes running on different CPUs or in different threads try to access the same
|
||||||
memory, then it is possible that strange things can happen or your system can lock
|
memory, then it is possible that strange things can happen or your system can lock
|
||||||
up. To avoid this, various types of mutual exclusion kernel functions are available.
|
up. To avoid this, various types of mutual exclusion kernel functions are available.
|
||||||
These indicate if a section of code is "locked" or "unlocked" so that simultaneous
|
These indicate if a section of code is "locked" or "unlocked" so that simultaneous
|
||||||
attempts to run it can not happen.
|
attempts to run it can not happen.
|
||||||
</p>
|
</p>
|
||||||
<h4 class='subsectionHead' id='mutex'><span class='titlemark'>0.12.1 </span> <a id='x1-450000.12.1'></a>Mutex</h4>
|
<h4 class='subsectionHead' id='mutex'><span class='titlemark'>0.12.1 </span> <a id='x1-450000.12.1'></a>Mutex</h4>
|
||||||
<!-- l. 1336 --><p class='noindent'>You can use kernel mutexes (mutual exclusions) in much the same manner that you
|
<!-- l. 1335 --><p class='noindent'>You can use kernel mutexes (mutual exclusions) in much the same manner that you
|
||||||
might deploy them in userland. This may be all that is needed to avoid collisions in
|
might deploy them in userland. This may be all that is needed to avoid collisions in
|
||||||
most cases.
|
most cases.
|
||||||
</p><!-- l. 1 --><p class='indent'>
|
</p><!-- l. 1 --><p class='indent'>
|
||||||
@ -3658,18 +3658,18 @@ most cases.
|
|||||||
<a id='x1-45078r39'></a><span class='ecrm-0500'>39</span>
|
<a id='x1-45078r39'></a><span class='ecrm-0500'>39</span>
|
||||||
<a id='x1-45080r40'></a><span class='ecrm-0500'>40</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor1802'><span class='ectt-0800'>"Mutex example"</span></span><span class='ectt-0800'>);</span>
|
<a id='x1-45080r40'></a><span class='ecrm-0500'>40</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor1802'><span class='ectt-0800'>"Mutex example"</span></span><span class='ectt-0800'>);</span>
|
||||||
<a id='x1-45082r41'></a><span class='ecrm-0500'>41</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor1803'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
<a id='x1-45082r41'></a><span class='ecrm-0500'>41</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor1803'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
||||||
<!-- l. 1341 --><p class='noindent'>
|
<!-- l. 1340 --><p class='noindent'>
|
||||||
</p>
|
</p>
|
||||||
<h4 class='subsectionHead' id='spinlocks'><span class='titlemark'>0.12.2 </span> <a id='x1-460000.12.2'></a>Spinlocks</h4>
|
<h4 class='subsectionHead' id='spinlocks'><span class='titlemark'>0.12.2 </span> <a id='x1-460000.12.2'></a>Spinlocks</h4>
|
||||||
<!-- l. 1343 --><p class='noindent'>As the name suggests, spinlocks lock up the CPU that the code is running on,
|
<!-- l. 1342 --><p class='noindent'>As the name suggests, spinlocks lock up the CPU that the code is running on,
|
||||||
taking 100% of its resources. Because of this you should only use the spinlock
|
taking 100% of its resources. Because of this you should only use the spinlock
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
mechanism around code which is likely to take no more than a few milliseconds to
|
mechanism around code which is likely to take no more than a few milliseconds to
|
||||||
run and so will not noticably slow anything down from the user’s point of
|
run and so will not noticeably slow anything down from the user’s point of
|
||||||
view.
|
view.
|
||||||
</p><!-- l. 1346 --><p class='indent'> The example here is <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>"irq safe"</span></span></span> in that if interrupts happen during the lock then
|
</p><!-- l. 1345 --><p class='indent'> The example here is <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>"irq safe"</span></span></span> in that if interrupts happen during the lock then
|
||||||
they will not be forgotten and will activate when the unlock happens, using the
|
they will not be forgotten and will activate when the unlock happens, using the
|
||||||
<code> <span class='ectt-1000'>flags</span>
|
<code> <span class='ectt-1000'>flags</span>
|
||||||
</code> variable to retain their state.
|
</code> variable to retain their state.
|
||||||
@ -3738,10 +3738,10 @@ they will not be forgotten and will activate when the unlock happens, using the
|
|||||||
<a id='x1-46123r61'></a><span class='ecrm-0500'>61</span>
|
<a id='x1-46123r61'></a><span class='ecrm-0500'>61</span>
|
||||||
<a id='x1-46125r62'></a><span class='ecrm-0500'>62</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor1858'><span class='ectt-0800'>"Spinlock example"</span></span><span class='ectt-0800'>);</span>
|
<a id='x1-46125r62'></a><span class='ecrm-0500'>62</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor1858'><span class='ectt-0800'>"Spinlock example"</span></span><span class='ectt-0800'>);</span>
|
||||||
<a id='x1-46127r63'></a><span class='ecrm-0500'>63</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor1859'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
<a id='x1-46127r63'></a><span class='ecrm-0500'>63</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor1859'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
||||||
<!-- l. 1350 --><p class='noindent'>
|
<!-- l. 1349 --><p class='noindent'>
|
||||||
</p>
|
</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>
|
<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. 1352 --><p class='noindent'>Read and write locks are specialised kinds of spinlocks so that you can exclusively
|
<!-- 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
|
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
|
from irqs which might also read and write to whatever you are concerned with
|
||||||
@ -3806,14 +3806,14 @@ module.
|
|||||||
<a id='x1-47106r53'></a><span class='ecrm-0500'>53</span>
|
<a id='x1-47106r53'></a><span class='ecrm-0500'>53</span>
|
||||||
<a id='x1-47108r54'></a><span class='ecrm-0500'>54</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor1906'><span class='ectt-0800'>"Read/Write locks example"</span></span><span class='ectt-0800'>);</span>
|
<a id='x1-47108r54'></a><span class='ecrm-0500'>54</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor1906'><span class='ectt-0800'>"Read/Write locks example"</span></span><span class='ectt-0800'>);</span>
|
||||||
<a id='x1-47110r55'></a><span class='ecrm-0500'>55</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor1907'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
<a id='x1-47110r55'></a><span class='ecrm-0500'>55</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor1907'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
||||||
<!-- l. 1358 --><p class='indent'> Of course, if you know for sure that there are no functions triggered by irqs
|
<!-- l. 1357 --><p class='indent'> Of course, if you know for sure that there are no functions triggered by irqs
|
||||||
which could possibly interfere with your logic then you can use the simpler
|
which could possibly interfere with your logic then you can use the simpler
|
||||||
<code> <span class='ectt-1000'>read_lock(&myrwlock)</span>
|
<code> <span class='ectt-1000'>read_lock(&myrwlock)</span>
|
||||||
</code> and <code> <span class='ectt-1000'>read_unlock(&myrwlock)</span>
|
</code> and <code> <span class='ectt-1000'>read_unlock(&myrwlock)</span>
|
||||||
</code> or the corresponding write functions.
|
</code> or the corresponding write functions.
|
||||||
</p>
|
</p>
|
||||||
<h4 class='subsectionHead' id='atomic-operations'><span class='titlemark'>0.12.4 </span> <a id='x1-480000.12.4'></a>Atomic operations</h4>
|
<h4 class='subsectionHead' id='atomic-operations'><span class='titlemark'>0.12.4 </span> <a id='x1-480000.12.4'></a>Atomic operations</h4>
|
||||||
<!-- l. 1361 --><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
|
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
|
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
|
can be confident that your addition, subtraction or bit flip did actually happen
|
||||||
@ -3898,21 +3898,21 @@ below.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- l. 1368 --><p class='noindent'>
|
<!-- l. 1367 --><p class='noindent'>
|
||||||
</p>
|
</p>
|
||||||
<h3 class='sectionHead' id='replacing-print-macros'><span class='titlemark'>0.13 </span> <a id='x1-490000.13'></a>Replacing Print Macros</h3>
|
<h3 class='sectionHead' id='replacing-print-macros'><span class='titlemark'>0.13 </span> <a id='x1-490000.13'></a>Replacing Print Macros</h3>
|
||||||
<!-- l. 1370 --><p class='noindent'>
|
<!-- l. 1369 --><p class='noindent'>
|
||||||
</p>
|
</p>
|
||||||
<h4 class='subsectionHead' id='replacement'><span class='titlemark'>0.13.1 </span> <a id='x1-500000.13.1'></a>Replacement</h4>
|
<h4 class='subsectionHead' id='replacement'><span class='titlemark'>0.13.1 </span> <a id='x1-500000.13.1'></a>Replacement</h4>
|
||||||
<!-- l. 1372 --><p class='noindent'>In Section <a href='#x1-80042'>2<!-- tex4ht:ref: sec:using_x --></a>, I said that X Window System and kernel module programming do not
|
<!-- l. 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
|
able to send messages to whichever tty the command to load the module came
|
||||||
from.
|
from.
|
||||||
</p><!-- l. 1376 --><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
|
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
|
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.
|
display, a network connection used with ssh, etc.
|
||||||
</p><!-- l. 1378 --><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
|
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
|
a pointer to a string write function, which we use to write a string to the
|
||||||
tty.
|
tty.
|
||||||
@ -3995,16 +3995,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-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-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='textcolor2032'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
<a id='x1-50154r77'></a><span class='ecrm-0500'>77</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor2032'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
||||||
<!-- l. 1383 --><p class='noindent'>
|
<!-- l. 1382 --><p class='noindent'>
|
||||||
</p>
|
</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>
|
<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. 1385 --><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
|
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
|
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,
|
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
|
and their use is rather simple and non-intrusive, compared to writing to a tty or a
|
||||||
file.
|
file.
|
||||||
</p><!-- l. 1389 --><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.
|
loaded, starts blinking the keyboard LEDs until it is unloaded.
|
||||||
</p><!-- l. 1 --><p class='indent'>
|
</p><!-- l. 1 --><p class='indent'>
|
||||||
</p>
|
</p>
|
||||||
@ -4100,7 +4100,7 @@ loaded, starts blinking the keyboard LEDs until it is unloaded.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- l. 1393 --><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
|
there might yet be some other tricks to try. Ever wondered what
|
||||||
<code> <span class='ectt-1000'>CONFIG_LL_DEBUG</span>
|
<code> <span class='ectt-1000'>CONFIG_LL_DEBUG</span>
|
||||||
</code> in <code> <span class='ectt-1000'>make menuconfig</span>
|
</code> in <code> <span class='ectt-1000'>make menuconfig</span>
|
||||||
@ -4111,22 +4111,22 @@ everything what your code does over a serial line. If you find yourself porting
|
|||||||
kernel to some new and former unsupported architecture, this is usually amongst the
|
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
|
first things that should be implemented. Logging over a netconsole might also be
|
||||||
worth a try.
|
worth a try.
|
||||||
</p><!-- l. 1400 --><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
|
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
|
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
|
should try to keep debug code to a minimum and make sure it does not show up in
|
||||||
production code.
|
production code.
|
||||||
</p><!-- l. 1404 --><p class='noindent'>
|
</p><!-- l. 1403 --><p class='noindent'>
|
||||||
</p>
|
</p>
|
||||||
<h3 class='sectionHead' id='scheduling-tasks'><span class='titlemark'>0.14 </span> <a id='x1-520000.14'></a>Scheduling Tasks</h3>
|
<h3 class='sectionHead' id='scheduling-tasks'><span class='titlemark'>0.14 </span> <a id='x1-520000.14'></a>Scheduling Tasks</h3>
|
||||||
<!-- l. 1406 --><p class='noindent'>There are two main ways of running tasks: tasklets and work queues. Tasklets are a
|
<!-- 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
|
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
|
triggered from an interrupt, whereas work queues are more complicated but also
|
||||||
better suited to running multiple things in a sequence.
|
better suited to running multiple things in a sequence.
|
||||||
</p><!-- l. 1410 --><p class='noindent'>
|
</p><!-- l. 1409 --><p class='noindent'>
|
||||||
</p>
|
</p>
|
||||||
<h4 class='subsectionHead' id='tasklets'><span class='titlemark'>0.14.1 </span> <a id='x1-530000.14.1'></a>Tasklets</h4>
|
<h4 class='subsectionHead' id='tasklets'><span class='titlemark'>0.14.1 </span> <a id='x1-530000.14.1'></a>Tasklets</h4>
|
||||||
<!-- l. 1412 --><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> <span class='ectt-1000'>tasklet_fn</span>
|
||||||
</code> function runs for a few seconds and in the mean time execution of the
|
</code> function runs for a few seconds and in the mean time execution of the
|
||||||
<code> <span class='ectt-1000'>example_tasklet_init</span>
|
<code> <span class='ectt-1000'>example_tasklet_init</span>
|
||||||
@ -4170,7 +4170,7 @@ better suited to running multiple things in a sequence.
|
|||||||
<a id='x1-53072r35'></a><span class='ecrm-0500'>35</span>
|
<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='textcolor2152'><span class='ectt-0800'>"Tasklet example"</span></span><span class='ectt-0800'>);</span>
|
<a id='x1-53074r36'></a><span class='ecrm-0500'>36</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor2152'><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='textcolor2153'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
<a id='x1-53076r37'></a><span class='ecrm-0500'>37</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor2153'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
||||||
<!-- l. 1417 --><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:
|
</code> should show:
|
||||||
|
|
||||||
|
|
||||||
@ -4182,11 +4182,11 @@ Example tasklet starts
|
|||||||
Example tasklet init continues...
|
Example tasklet init continues...
|
||||||
Example tasklet ends
|
Example tasklet ends
|
||||||
</pre>
|
</pre>
|
||||||
<!-- l. 1424 --><p class='nopar'>
|
<!-- l. 1423 --><p class='nopar'>
|
||||||
</p><!-- l. 1426 --><p class='noindent'>
|
</p><!-- l. 1425 --><p class='noindent'>
|
||||||
</p>
|
</p>
|
||||||
<h4 class='subsectionHead' id='work-queues'><span class='titlemark'>0.14.2 </span> <a id='x1-540000.14.2'></a>Work queues</h4>
|
<h4 class='subsectionHead' id='work-queues'><span class='titlemark'>0.14.2 </span> <a id='x1-540000.14.2'></a>Work queues</h4>
|
||||||
<!-- l. 1428 --><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.
|
Completely Fair Scheduler (CFS) to execute work within the queue.
|
||||||
</p><!-- l. 1 --><p class='indent'>
|
</p><!-- l. 1 --><p class='indent'>
|
||||||
</p>
|
</p>
|
||||||
@ -4224,19 +4224,19 @@ Completely Fair Scheduler (CFS) to execute work within the queue.
|
|||||||
<a id='x1-54064r32'></a><span class='ecrm-0500'>32</span>
|
<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='textcolor2181'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span>
|
<a id='x1-54066r33'></a><span class='ecrm-0500'>33</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor2181'><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='textcolor2182'><span class='ectt-0800'>"Workqueue example"</span></span><span class='ectt-0800'>);</span></pre>
|
<a id='x1-54068r34'></a><span class='ecrm-0500'>34</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor2182'><span class='ectt-0800'>"Workqueue example"</span></span><span class='ectt-0800'>);</span></pre>
|
||||||
<!-- l. 1433 --><p class='noindent'>
|
<!-- l. 1432 --><p class='noindent'>
|
||||||
</p>
|
</p>
|
||||||
<h3 class='sectionHead' id='interrupt-handlers'><span class='titlemark'>0.15 </span> <a id='x1-550000.15'></a>Interrupt Handlers</h3>
|
<h3 class='sectionHead' id='interrupt-handlers'><span class='titlemark'>0.15 </span> <a id='x1-550000.15'></a>Interrupt Handlers</h3>
|
||||||
<!-- l. 1435 --><p class='noindent'>
|
<!-- l. 1434 --><p class='noindent'>
|
||||||
</p>
|
</p>
|
||||||
<h4 class='subsectionHead' id='interrupt-handlers1'><span class='titlemark'>0.15.1 </span> <a id='x1-560000.15.1'></a>Interrupt Handlers</h4>
|
<h4 class='subsectionHead' id='interrupt-handlers1'><span class='titlemark'>0.15.1 </span> <a id='x1-560000.15.1'></a>Interrupt Handlers</h4>
|
||||||
<!-- l. 1437 --><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
|
response to a process asking for it, either by dealing with a special file, sending an
|
||||||
<code> <span class='ectt-1000'>ioctl()</span>
|
<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
|
</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
|
requests. Another job, which is every bit as important, is to speak to the hardware
|
||||||
connected to the machine.
|
connected to the machine.
|
||||||
</p><!-- l. 1441 --><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,
|
computer’s hardware. The first type is when the CPU gives orders to the hardware,
|
||||||
the order is when the hardware needs to tell the CPU something. The second, called
|
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
|
interrupts, is much harder to implement because it has to be dealt with when
|
||||||
@ -4246,14 +4246,14 @@ lost.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
</p><!-- l. 1446 --><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
|
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
|
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
|
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
|
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
|
device). If at all possible, it is better to declare an interrupt handler to be
|
||||||
long.
|
long.
|
||||||
</p><!-- l. 1452 --><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
|
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
|
only when the more important one is done), saves certain parameters on
|
||||||
the stack and calls the interrupt handler. This means that certain things
|
the stack and calls the interrupt handler. This means that certain things
|
||||||
@ -4265,10 +4265,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
|
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
|
possible – and when it does, everything allowed in kernel modules will be
|
||||||
allowed.
|
allowed.
|
||||||
</p><!-- l. 1458 --><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> <span class='ectt-1000'>request_irq()</span>
|
||||||
</code> to get your interrupt handler called when the relevant IRQ is received.
|
</code> to get your interrupt handler called when the relevant IRQ is received.
|
||||||
</p><!-- l. 1460 --><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
|
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
|
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
|
controller A. Of course, that requires that the kernel finds out which IRQ it
|
||||||
@ -4278,11 +4278,11 @@ them requires handlers to be written in assembler, so they do not really
|
|||||||
fit into the kernel. They can be made to work similar to the others, but
|
fit into the kernel. They can be made to work similar to the others, but
|
||||||
after that procedure, they are no longer any faster than "common" IRQs.
|
after that procedure, they are no longer any faster than "common" IRQs.
|
||||||
SMP enabled kernels running on systems with more than one processor
|
SMP enabled kernels running on systems with more than one processor
|
||||||
need to solve another truckload of problems. It is not enough to know if
|
need to solve another truckload of problems. It is not enough to know if a
|
||||||
a certain IRQs has happend, it’s also important for what CPU(s) it was
|
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"
|
for. People still interested in more details, might want to refer to "APIC"
|
||||||
now.
|
now.
|
||||||
</p><!-- l. 1469 --><p class='indent'> This function receives the IRQ number, the name of the function,
|
</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
|
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.
|
interrupt handler. Usually there is a certain number of IRQs available.
|
||||||
How many IRQs there are is hardware-dependent. The flags can include
|
How many IRQs there are is hardware-dependent. The flags can include
|
||||||
@ -4295,16 +4295,16 @@ already a handler on this IRQ, or if you are both willing to share.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
</p><!-- l. 1475 --><p class='noindent'>
|
</p><!-- l. 1474 --><p class='noindent'>
|
||||||
</p>
|
</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>
|
<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. 1477 --><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
|
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
|
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
|
it is better for the input to trigger the CPU to then run a particular handling
|
||||||
function.
|
function.
|
||||||
</p><!-- l. 1481 --><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
|
an LED is connected to GPIO 4. You can change those numbers to whatever is
|
||||||
appropriate for your board.
|
appropriate for your board.
|
||||||
</p><!-- l. 1 --><p class='indent'>
|
</p><!-- l. 1 --><p class='indent'>
|
||||||
@ -4454,14 +4454,14 @@ appropriate for your board.
|
|||||||
<a id='x1-57286r143'></a><span class='ecrm-0500'>143</span>
|
<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='textcolor2289'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span>
|
<a id='x1-57288r144'></a><span class='ecrm-0500'>144</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor2289'><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='textcolor2290'><span class='ectt-0800'>"Handle some GPIO interrupts"</span></span><span class='ectt-0800'>);</span></pre>
|
<a id='x1-57290r145'></a><span class='ecrm-0500'>145</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor2290'><span class='ectt-0800'>"Handle some GPIO interrupts"</span></span><span class='ectt-0800'>);</span></pre>
|
||||||
<!-- l. 1486 --><p class='noindent'>
|
<!-- l. 1485 --><p class='noindent'>
|
||||||
</p>
|
</p>
|
||||||
<h4 class='subsectionHead' id='bottom-half'><span class='titlemark'>0.15.3 </span> <a id='x1-580000.15.3'></a>Bottom Half</h4>
|
<h4 class='subsectionHead' id='bottom-half'><span class='titlemark'>0.15.3 </span> <a id='x1-580000.15.3'></a>Bottom Half</h4>
|
||||||
<!-- l. 1488 --><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
|
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
|
is to combine it with a tasklet. This pushes the bulk of the work off into the
|
||||||
scheduler.
|
scheduler.
|
||||||
</p><!-- l. 1492 --><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.
|
when an interrupt is triggered.
|
||||||
</p><!-- l. 1 --><p class='indent'>
|
</p><!-- l. 1 --><p class='indent'>
|
||||||
</p>
|
</p>
|
||||||
@ -4626,10 +4626,10 @@ when an interrupt is triggered.
|
|||||||
<a id='x1-58318r159'></a><span class='ecrm-0500'>159</span>
|
<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='textcolor2411'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span>
|
<a id='x1-58320r160'></a><span class='ecrm-0500'>160</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor2411'><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='textcolor2412'><span class='ectt-0800'>"Interrupt with top and bottom half"</span></span><span class='ectt-0800'>);</span></pre>
|
<a id='x1-58322r161'></a><span class='ecrm-0500'>161</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor2412'><span class='ectt-0800'>"Interrupt with top and bottom half"</span></span><span class='ectt-0800'>);</span></pre>
|
||||||
<!-- l. 1496 --><p class='noindent'>
|
<!-- l. 1495 --><p class='noindent'>
|
||||||
</p>
|
</p>
|
||||||
<h3 class='sectionHead' id='crypto'><span class='titlemark'>0.16 </span> <a id='x1-590000.16'></a>Crypto</h3>
|
<h3 class='sectionHead' id='crypto'><span class='titlemark'>0.16 </span> <a id='x1-590000.16'></a>Crypto</h3>
|
||||||
<!-- l. 1498 --><p class='noindent'>At the dawn of the internet, everybody trusted everybody completely…but that did
|
<!-- 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
|
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
|
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
|
||||||
@ -4638,10 +4638,10 @@ favourite hash functions.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
</p><!-- l. 1503 --><p class='noindent'>
|
</p><!-- l. 1502 --><p class='noindent'>
|
||||||
</p>
|
</p>
|
||||||
<h4 class='subsectionHead' id='hash-functions'><span class='titlemark'>0.16.1 </span> <a id='x1-600000.16.1'></a>Hash functions</h4>
|
<h4 class='subsectionHead' id='hash-functions'><span class='titlemark'>0.16.1 </span> <a id='x1-600000.16.1'></a>Hash functions</h4>
|
||||||
<!-- l. 1506 --><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.
|
demonstration of how to calculate a sha256 hash within a kernel module.
|
||||||
</p><!-- l. 1 --><p class='indent'>
|
</p><!-- l. 1 --><p class='indent'>
|
||||||
</p>
|
</p>
|
||||||
@ -4707,21 +4707,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-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='textcolor2462'><span class='ectt-0800'>"sha256 hash test"</span></span><span class='ectt-0800'>);</span>
|
<a id='x1-60122r61'></a><span class='ecrm-0500'>61</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor2462'><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='textcolor2463'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
<a id='x1-60124r62'></a><span class='ecrm-0500'>62</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor2463'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
||||||
<!-- l. 1511 --><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><!-- l. 1 --><p class='indent'>
|
||||||
</p>
|
</p>
|
||||||
<pre class='fancyvrb' id='fancyvrb68'><a id='x1-60129r1'></a><span class='ecrm-0500'>1</span><span class='ectt-1000'>make</span>
|
<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-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>
|
<a id='x1-60133r3'></a><span class='ecrm-0500'>3</span><span class='ectt-1000'>dmesg</span></pre>
|
||||||
<!-- l. 1519 --><p class='indent'> And you should see that the hash was calculated for the test string.
|
<!-- l. 1518 --><p class='indent'> And you should see that the hash was calculated for the test string.
|
||||||
</p><!-- l. 1521 --><p class='indent'> Finally, remove the test module:
|
</p><!-- l. 1520 --><p class='indent'> Finally, remove the test module:
|
||||||
</p><!-- l. 1 --><p class='indent'>
|
</p><!-- l. 1 --><p class='indent'>
|
||||||
</p>
|
</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>
|
<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. 1527 --><p class='noindent'>
|
<!-- l. 1526 --><p class='noindent'>
|
||||||
</p>
|
</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>
|
<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. 1529 --><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.
|
and a password.
|
||||||
</p><!-- l. 1 --><p class='indent'>
|
</p><!-- l. 1 --><p class='indent'>
|
||||||
</p>
|
</p>
|
||||||
@ -4922,13 +4922,13 @@ and a password.
|
|||||||
<a id='x1-61390r195'></a><span class='ecrm-0500'>195</span>
|
<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='textcolor2609'><span class='ectt-0800'>"Symmetric key encryption example"</span></span><span class='ectt-0800'>);</span>
|
<a id='x1-61392r196'></a><span class='ecrm-0500'>196</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor2609'><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='textcolor2610'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
<a id='x1-61394r197'></a><span class='ecrm-0500'>197</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor2610'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
||||||
<!-- l. 1533 --><p class='noindent'>
|
<!-- l. 1532 --><p class='noindent'>
|
||||||
</p>
|
</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>
|
<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. 1535 --><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
|
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
|
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
|
resume a device a device model was added. An example is shown below, and you can
|
||||||
use this as a template to add your own suspend, resume or other interface
|
use this as a template to add your own suspend, resume or other interface
|
||||||
functions.
|
functions.
|
||||||
</p><!-- l. 1 --><p class='indent'>
|
</p><!-- l. 1 --><p class='indent'>
|
||||||
@ -5035,24 +5035,23 @@ functions.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- l. 1541 --><p class='noindent'>
|
<!-- l. 1540 --><p class='noindent'>
|
||||||
</p>
|
</p>
|
||||||
<h3 class='sectionHead' id='optimizations'><span class='titlemark'>0.18 </span> <a id='x1-630000.18'></a>Optimizations</h3>
|
<h3 class='sectionHead' id='optimizations'><span class='titlemark'>0.18 </span> <a id='x1-630000.18'></a>Optimizations</h3>
|
||||||
<!-- l. 1543 --><p class='noindent'>
|
<!-- l. 1542 --><p class='noindent'>
|
||||||
</p>
|
</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>
|
<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. 1545 --><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
|
especially if it is handling an interrupt or doing something which might
|
||||||
cause noticible latency. If your code contains boolean conditions and if you
|
cause noticeable latency. If your code contains boolean conditions and if
|
||||||
know that the conditions are almost always likely to evaluate as either
|
you know that the conditions are almost always likely to evaluate as either
|
||||||
<code> <span class='ectt-1000'>true</span>
|
<code> <span class='ectt-1000'>true</span>
|
||||||
</code> or <code> <span class='ectt-1000'>false</span>
|
</code> or <code> <span class='ectt-1000'>false</span>
|
||||||
</code>, then you can allow the compiler to optimize for this using the
|
</code>, then you can allow the compiler to optimize for this using the
|
||||||
<code> <span class='ectt-1000'>likely</span>
|
<code> <span class='ectt-1000'>likely</span>
|
||||||
</code> and <code> <span class='ectt-1000'>unlikely</span>
|
</code> and <code> <span class='ectt-1000'>unlikely</span>
|
||||||
</code> macros.
|
</code> macros. For example, when allocating memory you are almost always expecting this
|
||||||
</p><!-- l. 1549 --><p class='indent'> For example, when allocating memory you are almost always expecting this to
|
to succeed.
|
||||||
succeed.
|
|
||||||
</p><!-- l. 1 --><p class='indent'>
|
</p><!-- l. 1 --><p class='indent'>
|
||||||
</p>
|
</p>
|
||||||
<pre class='fancyvrb' id='fancyvrb72'><a id='x1-64012r1'></a><span class='ecrm-0500'>1</span><span class='ectt-0800'>bvl = bvec_alloc(gfp_mask, nr_iovecs, &idx);</span>
|
<pre class='fancyvrb' id='fancyvrb72'><a id='x1-64012r1'></a><span class='ecrm-0500'>1</span><span class='ectt-0800'>bvl = bvec_alloc(gfp_mask, nr_iovecs, &idx);</span>
|
||||||
@ -5061,50 +5060,50 @@ succeed.
|
|||||||
<a id='x1-64018r4'></a><span class='ecrm-0500'>4</span><span class='ectt-0800'> bio = NULL;</span>
|
<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='textcolor2688'><span class='ectt-0800'>goto</span></span><span class='ectt-0800'> out;</span>
|
<a id='x1-64020r5'></a><span class='ecrm-0500'>5</span><span class='ectt-0800'> </span><span id='textcolor2688'><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>
|
<a id='x1-64022r6'></a><span class='ecrm-0500'>6</span><span class='ectt-0800'>}</span></pre>
|
||||||
<!-- l. 1560 --><p class='indent'> When the <code> <span class='ectt-1000'>unlikely</span>
|
<!-- l. 1558 --><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
|
</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
|
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
|
avoids flushing the processor pipeline. The opposite happens if you use the
|
||||||
<code> <span class='ectt-1000'>likely</span>
|
<code> <span class='ectt-1000'>likely</span>
|
||||||
</code> macro.
|
</code> macro.
|
||||||
</p><!-- l. 1564 --><p class='noindent'>
|
</p><!-- l. 1562 --><p class='noindent'>
|
||||||
</p>
|
</p>
|
||||||
<h3 class='sectionHead' id='common-pitfalls'><span class='titlemark'>0.19 </span> <a id='x1-650000.19'></a>Common Pitfalls</h3>
|
<h3 class='sectionHead' id='common-pitfalls'><span class='titlemark'>0.19 </span> <a id='x1-650000.19'></a>Common Pitfalls</h3>
|
||||||
<!-- l. 1567 --><p class='noindent'>
|
<!-- l. 1565 --><p class='noindent'>
|
||||||
</p>
|
</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>
|
<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. 1569 --><p class='noindent'>You can not do that. In a kernel module, you can only use kernel functions which are
|
<!-- l. 1567 --><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>.
|
the functions you can see in <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>/proc/kallsyms</span></span></span>.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</p><!-- l. 1572 --><p class='noindent'>
|
</p><!-- l. 1570 --><p class='noindent'>
|
||||||
</p>
|
</p>
|
||||||
<h4 class='subsectionHead' id='disabling-interrupts'><span class='titlemark'>0.19.2 </span> <a id='x1-670000.19.2'></a>Disabling interrupts</h4>
|
<h4 class='subsectionHead' id='disabling-interrupts'><span class='titlemark'>0.19.2 </span> <a id='x1-670000.19.2'></a>Disabling interrupts</h4>
|
||||||
<!-- l. 1574 --><p class='noindent'>You might need to do this for a short time and that is OK, but if you do not enable
|
<!-- l. 1572 --><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
|
them afterwards, your system will be stuck and you will have to power it
|
||||||
off.
|
off.
|
||||||
</p><!-- l. 1576 --><p class='noindent'>
|
</p><!-- l. 1574 --><p class='noindent'>
|
||||||
</p>
|
</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>
|
<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. 1578 --><p class='noindent'>For people seriously interested in kernel programming, I recommend <a href='https://kernelnewbies.org'>kernelnewbies.org</a>
|
<!-- l. 1576 --><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
|
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,
|
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
|
as Linus Torvalds said, the best way to learn the kernel is to read the source code
|
||||||
yourself.
|
yourself.
|
||||||
</p><!-- l. 1581 --><p class='indent'> If you are interested in more examples of short kernel modules then searching on
|
</p><!-- l. 1579 --><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
|
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
|
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
|
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
|
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
|
how to defend systems and learning about existing security mechanisms within the
|
||||||
kernel.
|
kernel.
|
||||||
</p><!-- l. 1584 --><p class='indent'> I hope I have helped you in your quest to become a better programmer, or at
|
</p><!-- l. 1582 --><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
|
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.
|
hope you publish them under the GPL, so I can use them too.
|
||||||
</p><!-- l. 1587 --><p class='indent'> If you would like to contribute to this guide or notice anything glaringly wrong,
|
</p><!-- l. 1585 --><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>.
|
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. 1589 --><p class='indent'> Happy hacking!
|
</p><!-- l. 1587 --><p class='indent'> Happy hacking!
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
<h2 class='titleHead'>The Linux Kernel Module Programming Guide</h2>
|
<h2 class='titleHead'>The Linux Kernel Module Programming Guide</h2>
|
||||||
<div class='author'><span class='ecrm-1200'>Peter Jay Salzman, Michael Burian, Ori Pomerantz, Bob Mottram, Jim Huang</span></div><br />
|
<div class='author'><span class='ecrm-1200'>Peter Jay Salzman, Michael Burian, Ori Pomerantz, Bob Mottram, Jim Huang</span></div><br />
|
||||||
<div class='date'><span class='ecrm-1200'>August 16, 2021</span></div>
|
<div class='date'><span class='ecrm-1200'>August 17, 2021</span></div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -280,7 +280,7 @@ module.
|
|||||||
<pre class='fancyvrb' id='fancyvrb10'><a id='x1-12008r1'></a><span class='ecrm-0500'>1</span><span id='textcolor3'><span class='ectt-0800'>/*</span></span>
|
<pre class='fancyvrb' id='fancyvrb10'><a id='x1-12008r1'></a><span class='ecrm-0500'>1</span><span id='textcolor3'><span class='ectt-0800'>/*</span></span>
|
||||||
<a id='x1-12010r2'></a><span class='ecrm-0500'>2</span><span id='textcolor4'><span class='ectt-0800'> * hello-1.c - The simplest kernel module.</span></span>
|
<a id='x1-12010r2'></a><span class='ecrm-0500'>2</span><span id='textcolor4'><span class='ectt-0800'> * hello-1.c - The simplest kernel module.</span></span>
|
||||||
<a id='x1-12012r3'></a><span class='ecrm-0500'>3</span><span id='textcolor5'><span class='ectt-0800'> */</span></span>
|
<a id='x1-12012r3'></a><span class='ecrm-0500'>3</span><span id='textcolor5'><span class='ectt-0800'> */</span></span>
|
||||||
<a id='x1-12014r4'></a><span class='ecrm-0500'>4</span><span id='textcolor6'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor7'><span class='ectt-0800'><linux/kernel.h> /* Needed for KERN_INFO */</span></span>
|
<a id='x1-12014r4'></a><span class='ecrm-0500'>4</span><span id='textcolor6'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor7'><span class='ectt-0800'><linux/kernel.h> /* Needed for pr_info() */</span></span>
|
||||||
<a id='x1-12016r5'></a><span class='ecrm-0500'>5</span><span id='textcolor8'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor9'><span class='ectt-0800'><linux/module.h> /* Needed by all modules */</span></span>
|
<a id='x1-12016r5'></a><span class='ecrm-0500'>5</span><span id='textcolor8'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor9'><span class='ectt-0800'><linux/module.h> /* Needed by all modules */</span></span>
|
||||||
<a id='x1-12018r6'></a><span class='ecrm-0500'>6</span>
|
<a id='x1-12018r6'></a><span class='ecrm-0500'>6</span>
|
||||||
<a id='x1-12020r7'></a><span class='ecrm-0500'>7</span><span id='textcolor10'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> init_module(</span><span id='textcolor11'><span class='ectt-0800'>void</span></span><span class='ectt-0800'>)</span>
|
<a id='x1-12020r7'></a><span class='ecrm-0500'>7</span><span id='textcolor10'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> init_module(</span><span id='textcolor11'><span class='ectt-0800'>void</span></span><span class='ectt-0800'>)</span>
|
||||||
@ -425,7 +425,7 @@ technique:
|
|||||||
<a id='x1-13010r3'></a><span class='ecrm-0500'>3</span><span id='textcolor30'><span class='ectt-0800'> * This is preferred over using init_module() and cleanup_module().</span></span>
|
<a id='x1-13010r3'></a><span class='ecrm-0500'>3</span><span id='textcolor30'><span class='ectt-0800'> * This is preferred over using init_module() and cleanup_module().</span></span>
|
||||||
<a id='x1-13012r4'></a><span class='ecrm-0500'>4</span><span id='textcolor31'><span class='ectt-0800'> */</span></span>
|
<a id='x1-13012r4'></a><span class='ecrm-0500'>4</span><span id='textcolor31'><span class='ectt-0800'> */</span></span>
|
||||||
<a id='x1-13014r5'></a><span class='ecrm-0500'>5</span><span id='textcolor32'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor33'><span class='ectt-0800'><linux/init.h> /* Needed for the macros */</span></span>
|
<a id='x1-13014r5'></a><span class='ecrm-0500'>5</span><span id='textcolor32'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor33'><span class='ectt-0800'><linux/init.h> /* Needed for the macros */</span></span>
|
||||||
<a id='x1-13016r6'></a><span class='ecrm-0500'>6</span><span id='textcolor34'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor35'><span class='ectt-0800'><linux/kernel.h> /* Needed for KERN_INFO */</span></span>
|
<a id='x1-13016r6'></a><span class='ecrm-0500'>6</span><span id='textcolor34'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor35'><span class='ectt-0800'><linux/kernel.h> /* Needed for pr_info() */</span></span>
|
||||||
<a id='x1-13018r7'></a><span class='ecrm-0500'>7</span><span id='textcolor36'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor37'><span class='ectt-0800'><linux/module.h> /* Needed by all modules */</span></span>
|
<a id='x1-13018r7'></a><span class='ecrm-0500'>7</span><span id='textcolor36'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor37'><span class='ectt-0800'><linux/module.h> /* Needed by all modules */</span></span>
|
||||||
<a id='x1-13020r8'></a><span class='ecrm-0500'>8</span>
|
<a id='x1-13020r8'></a><span class='ecrm-0500'>8</span>
|
||||||
<a id='x1-13022r9'></a><span class='ecrm-0500'>9</span><span id='textcolor38'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor39'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> __init hello_2_init(</span><span id='textcolor40'><span class='ectt-0800'>void</span></span><span class='ectt-0800'>)</span>
|
<a id='x1-13022r9'></a><span class='ecrm-0500'>9</span><span id='textcolor38'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor39'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> __init hello_2_init(</span><span id='textcolor40'><span class='ectt-0800'>void</span></span><span class='ectt-0800'>)</span>
|
||||||
@ -462,7 +462,7 @@ is as simple as this:
|
|||||||
see, some things get hardwired into the kernel (<span class='obeylines-h'><span class='verb'><span class='ectt-1000'>obj-y</span></span></span>) but where are all those <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>obj-m</span></span></span>
|
see, some things get hardwired into the kernel (<span class='obeylines-h'><span class='verb'><span class='ectt-1000'>obj-y</span></span></span>) but where are all those <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>obj-m</span></span></span>
|
||||||
gone? Those familiar with shell scripts will easily be able to spot them. For those not,
|
gone? Those familiar with shell scripts will easily be able to spot them. For those not,
|
||||||
the <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>obj-$(CONFIG_FOO)</span></span></span> entries you see everywhere expand into <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>obj-y</span></span></span> or <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>obj-m</span></span></span>,
|
the <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>obj-$(CONFIG_FOO)</span></span></span> entries you see everywhere expand into <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>obj-y</span></span></span> or <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>obj-m</span></span></span>,
|
||||||
depending on whether the <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>CONFIG_FOO</span></span></span> variable has been set to y or m. While we are
|
depending on whether the <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>CONFIG_FOO</span></span></span> variable has been set to <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>y</span></span></span> or <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>m</span></span></span>. While we are
|
||||||
at it, those were exactly the kind of variables that you have set in the <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>.config</span></span></span> file in
|
at it, those were exactly the kind of variables that you have set in the <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>.config</span></span></span> file in
|
||||||
the top-level directory of Linux kernel source tree, the last time when you said
|
the top-level directory of Linux kernel source tree, the last time when you said
|
||||||
<code> <span class='ectt-1000'>make menuconfig</span>
|
<code> <span class='ectt-1000'>make menuconfig</span>
|
||||||
@ -494,7 +494,7 @@ memory: 236k freed, this is precisely what the kernel is freeing.
|
|||||||
<a id='x1-14009r2'></a><span class='ecrm-0500'>2</span><span id='textcolor57'><span class='ectt-0800'> * hello-3.c - Illustrating the __init, __initdata and __exit macros.</span></span>
|
<a id='x1-14009r2'></a><span class='ecrm-0500'>2</span><span id='textcolor57'><span class='ectt-0800'> * hello-3.c - Illustrating the __init, __initdata and __exit macros.</span></span>
|
||||||
<a id='x1-14011r3'></a><span class='ecrm-0500'>3</span><span id='textcolor58'><span class='ectt-0800'> */</span></span>
|
<a id='x1-14011r3'></a><span class='ecrm-0500'>3</span><span id='textcolor58'><span class='ectt-0800'> */</span></span>
|
||||||
<a id='x1-14013r4'></a><span class='ecrm-0500'>4</span><span id='textcolor59'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor60'><span class='ectt-0800'><linux/init.h> /* Needed for the macros */</span></span>
|
<a id='x1-14013r4'></a><span class='ecrm-0500'>4</span><span id='textcolor59'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor60'><span class='ectt-0800'><linux/init.h> /* Needed for the macros */</span></span>
|
||||||
<a id='x1-14015r5'></a><span class='ecrm-0500'>5</span><span id='textcolor61'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor62'><span class='ectt-0800'><linux/kernel.h> /* Needed for KERN_INFO */</span></span>
|
<a id='x1-14015r5'></a><span class='ecrm-0500'>5</span><span id='textcolor61'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor62'><span class='ectt-0800'><linux/kernel.h> /* Needed for pr_info() */</span></span>
|
||||||
<a id='x1-14017r6'></a><span class='ecrm-0500'>6</span><span id='textcolor63'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor64'><span class='ectt-0800'><linux/module.h> /* Needed by all modules */</span></span>
|
<a id='x1-14017r6'></a><span class='ecrm-0500'>6</span><span id='textcolor63'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor64'><span class='ectt-0800'><linux/module.h> /* Needed by all modules */</span></span>
|
||||||
<a id='x1-14019r7'></a><span class='ecrm-0500'>7</span>
|
<a id='x1-14019r7'></a><span class='ecrm-0500'>7</span>
|
||||||
<a id='x1-14021r8'></a><span class='ecrm-0500'>8</span><span id='textcolor65'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor66'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> hello3_data __initdata = 3;</span>
|
<a id='x1-14021r8'></a><span class='ecrm-0500'>8</span><span id='textcolor65'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor66'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> hello3_data __initdata = 3;</span>
|
||||||
@ -543,7 +543,7 @@ example.
|
|||||||
<a id='x1-15005r2'></a><span class='ecrm-0500'>2</span><span id='textcolor82'><span class='ectt-0800'> * hello-4.c - Demonstrates module documentation.</span></span>
|
<a id='x1-15005r2'></a><span class='ecrm-0500'>2</span><span id='textcolor82'><span class='ectt-0800'> * hello-4.c - Demonstrates module documentation.</span></span>
|
||||||
<a id='x1-15007r3'></a><span class='ecrm-0500'>3</span><span id='textcolor83'><span class='ectt-0800'> */</span></span>
|
<a id='x1-15007r3'></a><span class='ecrm-0500'>3</span><span id='textcolor83'><span class='ectt-0800'> */</span></span>
|
||||||
<a id='x1-15009r4'></a><span class='ecrm-0500'>4</span><span id='textcolor84'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor85'><span class='ectt-0800'><linux/init.h> /* Needed for the macros */</span></span>
|
<a id='x1-15009r4'></a><span class='ecrm-0500'>4</span><span id='textcolor84'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor85'><span class='ectt-0800'><linux/init.h> /* Needed for the macros */</span></span>
|
||||||
<a id='x1-15011r5'></a><span class='ecrm-0500'>5</span><span id='textcolor86'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor87'><span class='ectt-0800'><linux/kernel.h> /* Needed for KERN_INFO */</span></span>
|
<a id='x1-15011r5'></a><span class='ecrm-0500'>5</span><span id='textcolor86'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor87'><span class='ectt-0800'><linux/kernel.h> /* Needed for pr_info() */</span></span>
|
||||||
<a id='x1-15013r6'></a><span class='ecrm-0500'>6</span><span id='textcolor88'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor89'><span class='ectt-0800'><linux/module.h> /* Needed by all modules */</span></span>
|
<a id='x1-15013r6'></a><span class='ecrm-0500'>6</span><span id='textcolor88'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor89'><span class='ectt-0800'><linux/module.h> /* Needed by all modules */</span></span>
|
||||||
<a id='x1-15015r7'></a><span class='ecrm-0500'>7</span>
|
<a id='x1-15015r7'></a><span class='ecrm-0500'>7</span>
|
||||||
<a id='x1-15017r8'></a><span class='ecrm-0500'>8</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor90'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span>
|
<a id='x1-15017r8'></a><span class='ecrm-0500'>8</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor90'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span>
|
||||||
@ -800,7 +800,7 @@ error as follows:
|
|||||||
insmod: error inserting 'poet_atkm.ko': -1 Invalid module format
|
insmod: error inserting 'poet_atkm.ko': -1 Invalid module format
|
||||||
</pre>
|
</pre>
|
||||||
<!-- l. 489 --><p class='nopar'>
|
<!-- l. 489 --><p class='nopar'>
|
||||||
</p><!-- l. 491 --><p class='indent'> Less cryptical information are logged to the systemd journal:
|
</p><!-- l. 491 --><p class='indent'> Less cryptic information is logged to the systemd journal:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -833,8 +833,8 @@ name: hello_4
|
|||||||
vermagic: 5.4.0-70-generic SMP mod_unload modversions
|
vermagic: 5.4.0-70-generic SMP mod_unload modversions
|
||||||
</pre>
|
</pre>
|
||||||
<!-- l. 513 --><p class='nopar'>
|
<!-- l. 513 --><p class='nopar'>
|
||||||
</p><!-- l. 515 --><p class='indent'> To overcome this problem we could resort to the <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>--force-vermagic</span></span></span>
|
</p><!-- l. 515 --><p class='indent'> To overcome this problem we could resort to the <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>--force-vermagic</span></span></span> option,
|
||||||
option, but this solution is potentially unsafe, and unquestionably inacceptable
|
but this solution is potentially unsafe, and unquestionably unacceptable
|
||||||
in production modules. Consequently, we want to compile our module in
|
in production modules. Consequently, we want to compile our module in
|
||||||
an environment which was identical to the one in which our precompiled
|
an environment which was identical to the one in which our precompiled
|
||||||
kernel was built. How to do this, is the subject of the remainder of this
|
kernel was built. How to do this, is the subject of the remainder of this
|
||||||
@ -847,11 +847,11 @@ tree: <code> <span class='ectt-1000'>cp /boot/config-</span><span id='textcolo
|
|||||||
</code>.
|
</code>.
|
||||||
</p><!-- l. 524 --><p class='indent'> Let’s focus again on the previous error message: a closer look at the version magic
|
</p><!-- l. 524 --><p class='indent'> Let’s focus again on the previous error message: a closer look at the version magic
|
||||||
strings suggests that, even with two configuration files which are exactly the same, a
|
strings suggests that, even with two configuration files which are exactly the same, a
|
||||||
slight difference in the version magic could be possible, and it is sufficient to
|
slight difference in the version magic could be possible, and it is sufficient to prevent
|
||||||
prevent insertion of the module into the kernel. That slight difference, namely
|
insertion of the module into the kernel. That slight difference, namely the
|
||||||
the custom string which appears in the module’s version magic and not in
|
custom string which appears in the module’s version magic and not in the
|
||||||
the kernel’s one, is due to a modification with respect to the original, in
|
kernel’s one, is due to a modification with respect to the original, in the
|
||||||
the makefile that some distribution include. Then, examine your <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>Makefile</span></span></span>,
|
makefile that some distributions include. Then, examine your <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>Makefile</span></span></span>,
|
||||||
and make sure that the specified version information matches exactly the
|
and make sure that the specified version information matches exactly the
|
||||||
one used for your current kernel. For example, you makefile could start as
|
one used for your current kernel. For example, you makefile could start as
|
||||||
follows:
|
follows:
|
||||||
@ -974,7 +974,7 @@ data into strings and write the string data using the low-level system call
|
|||||||
<a id='x1-21026r6'></a><span class='ecrm-0500'>6</span><span class='ectt-0800'> </span><span id='textcolor262'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> 0;</span>
|
<a id='x1-21026r6'></a><span class='ecrm-0500'>6</span><span class='ectt-0800'> </span><span id='textcolor262'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> 0;</span>
|
||||||
<a id='x1-21028r7'></a><span class='ecrm-0500'>7</span><span class='ectt-0800'>}</span></pre>
|
<a id='x1-21028r7'></a><span class='ecrm-0500'>7</span><span class='ectt-0800'>}</span></pre>
|
||||||
<!-- l. 608 --><p class='indent'> with <code> <span class='ectt-1000'>gcc -Wall -o hello hello.c</span>
|
<!-- l. 608 --><p class='indent'> with <code> <span class='ectt-1000'>gcc -Wall -o hello hello.c</span>
|
||||||
</code>. Run the exectable with <code> <span class='ectt-1000'>strace ./hello</span>
|
</code>. Run the executable with <code> <span class='ectt-1000'>strace ./hello</span>
|
||||||
</code>. Are you impressed? Every line you see corresponds to a system call. <a href='https://strace.io/'>strace</a> is a
|
</code>. Are you impressed? Every line you see corresponds to a system call. <a href='https://strace.io/'>strace</a> is a
|
||||||
handy program that gives you details about what system calls a program is
|
handy program that gives you details about what system calls a program is
|
||||||
making, including which call is made, what its arguments are and what it
|
making, including which call is made, what its arguments are and what it
|
||||||
@ -1036,8 +1036,8 @@ symbols.
|
|||||||
entire kernel, so this is definitely an issue. The best way to deal with this is to declare
|
entire kernel, so this is definitely an issue. The best way to deal with this is to declare
|
||||||
all your variables as static and to use a well-defined prefix for your symbols. By
|
all your variables as static and to use a well-defined prefix for your symbols. By
|
||||||
convention, all kernel prefixes are lowercase. If you do not want to declare everything
|
convention, all kernel prefixes are lowercase. If you do not want to declare everything
|
||||||
as static, another option is to declare a symbol table and register it with a kernel. We
|
as static, another option is to declare a symbol table and register it with the kernel.
|
||||||
will get to this later.
|
We will get to this later.
|
||||||
</p><!-- l. 652 --><p class='indent'> The file <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>/proc/kallsyms</span></span></span> holds all the symbols that the kernel knows about and
|
</p><!-- l. 652 --><p class='indent'> The file <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>/proc/kallsyms</span></span></span> holds all the symbols that the kernel knows about and
|
||||||
which are therefore accessible to your modules since they share the kernel’s
|
which are therefore accessible to your modules since they share the kernel’s
|
||||||
codespace.
|
codespace.
|
||||||
@ -1583,7 +1583,7 @@ conditional compilation directives. The way to do this to compare the macro
|
|||||||
information to processes — the <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>/proc</span></span></span> file system. Originally designed to allow easy
|
information to processes — the <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>/proc</span></span></span> file system. Originally designed to allow easy
|
||||||
access to information about processes (hence the name), it is now used by every bit
|
access to information about processes (hence the name), it is now used by every bit
|
||||||
of the kernel which has something interesting to report, such as <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>/proc/modules</span></span></span>
|
of the kernel which has something interesting to report, such as <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>/proc/modules</span></span></span>
|
||||||
which provides the list of modules and <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>/proc/meminfo</span></span></span> which stats memory usage
|
which provides the list of modules and <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>/proc/meminfo</span></span></span> which gathers memory usage
|
||||||
statistics.
|
statistics.
|
||||||
</p><!-- l. 943 --><p class='indent'> The method to use the proc file system is very similar to the one used with device
|
</p><!-- l. 943 --><p class='indent'> The method to use the proc file system is very similar to the one used with device
|
||||||
drivers — a structure is created with all the information needed for the <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>/proc</span></span></span> file,
|
drivers — a structure is created with all the information needed for the <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>/proc</span></span></span> file,
|
||||||
@ -1620,7 +1620,7 @@ function <code> <span class='ectt-1000'>procfile_read</span>
|
|||||||
</code>. The return value is a <code> <span id='textcolor548'><span class='ectt-1000'>struct</span></span><span class='ectt-1000'> proc_dir_entry</span>
|
</code>. The return value is a <code> <span id='textcolor548'><span class='ectt-1000'>struct</span></span><span class='ectt-1000'> proc_dir_entry</span>
|
||||||
</code>, and it will be used to configure the file <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>/proc/helloworld</span></span></span> (for example, the owner
|
</code>, and it will be used to configure the file <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>/proc/helloworld</span></span></span> (for example, the owner
|
||||||
of this file). A null return value means that the creation has failed.
|
of this file). A null return value means that the creation has failed.
|
||||||
</p><!-- l. 959 --><p class='indent'> Each time, everytime the file <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>/proc/helloworld</span></span></span> is read, the function
|
</p><!-- l. 959 --><p class='indent'> Every time the file <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>/proc/helloworld</span></span></span> is read, the function
|
||||||
<code> <span class='ectt-1000'>procfile_read</span>
|
<code> <span class='ectt-1000'>procfile_read</span>
|
||||||
</code> is called. Two parameters of this function are very important: the buffer
|
</code> is called. Two parameters of this function are very important: the buffer
|
||||||
(the second parameter) and the offset (the fourth one). The content of the
|
(the second parameter) and the offset (the fourth one). The content of the
|
||||||
@ -2200,7 +2200,7 @@ the same way as in the previous example.
|
|||||||
<!-- l. 1076 --><p class='indent'> If you want more information, you can read this web page:
|
<!-- l. 1076 --><p class='indent'> If you want more information, you can read this web page:
|
||||||
</p>
|
</p>
|
||||||
<ul class='itemize1'>
|
<ul class='itemize1'>
|
||||||
<li class='itemize'><a class='url' href='http://lwn.net/Articles/22355/'><span class='ectt-1000'>http://lwn.net/Articles/22355/</span></a>
|
<li class='itemize'><a class='url' href='https://lwn.net/Articles/22355/'><span class='ectt-1000'>https://lwn.net/Articles/22355/</span></a>
|
||||||
</li>
|
</li>
|
||||||
<li class='itemize'><a class='url' href='https://kernelnewbies.org/Documents/SeqFileHowTo'><span class='ectt-1000'>https://kernelnewbies.org/Documents/SeqFileHowTo</span></a></li></ul>
|
<li class='itemize'><a class='url' href='https://kernelnewbies.org/Documents/SeqFileHowTo'><span class='ectt-1000'>https://kernelnewbies.org/Documents/SeqFileHowTo</span></a></li></ul>
|
||||||
<!-- l. 1083 --><p class='indent'> You can also read the code of <a href='https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/fs/seq_file.c'>fs/seq_file.c</a> in the linux kernel.
|
<!-- l. 1083 --><p class='indent'> You can also read the code of <a href='https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/fs/seq_file.c'>fs/seq_file.c</a> in the linux kernel.
|
||||||
@ -2327,7 +2327,7 @@ device file to write things to the modem (either modem commands or data to
|
|||||||
be sent through the phone line) and read things from the modem (either
|
be sent through the phone line) and read things from the modem (either
|
||||||
responses for commands or the data received through the phone line). However,
|
responses for commands or the data received through the phone line). However,
|
||||||
this leaves open the question of what to do when you need to talk to the
|
this leaves open the question of what to do when you need to talk to the
|
||||||
serial port itself, for example to send the rate at which data is sent and
|
serial port itself, for example to configure the rate at which data is sent and
|
||||||
received.
|
received.
|
||||||
|
|
||||||
|
|
||||||
@ -2360,7 +2360,7 @@ ioctl.c.
|
|||||||
</p><!-- l. 1155 --><p class='indent'> If you want to use ioctls in your own kernel modules, it is best to receive an
|
</p><!-- l. 1155 --><p class='indent'> If you want to use ioctls in your own kernel modules, it is best to receive an
|
||||||
official ioctl assignment, so if you accidentally get somebody else’s ioctls, or if they
|
official ioctl assignment, so if you accidentally get somebody else’s ioctls, or if they
|
||||||
get yours, you’ll know something is wrong. For more information, consult the kernel
|
get yours, you’ll know something is wrong. For more information, consult the kernel
|
||||||
source tree at <a href='https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/Documentation/driver-api/ioctl.rst'>Documentation/driver-api/ioctl.rst</a>.
|
source tree at <a href='https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/Documentation/userspace-api/ioctl/ioctl-number.rst'>Documentation/userspace-api/ioctl/ioctl-number.rst</a>.
|
||||||
</p><!-- l. 1 --><p class='indent'>
|
</p><!-- l. 1 --><p class='indent'>
|
||||||
</p>
|
</p>
|
||||||
<pre class='fancyvrb' id='fancyvrb49'><a id='x1-39009r1'></a><span class='ecrm-0500'>1</span><span id='textcolor964'><span class='ectt-0800'>/*</span></span>
|
<pre class='fancyvrb' id='fancyvrb49'><a id='x1-39009r1'></a><span class='ecrm-0500'>1</span><span id='textcolor964'><span class='ectt-0800'>/*</span></span>
|
||||||
@ -2843,30 +2843,30 @@ source tree at <a href='https://git.kernel.org/pub/scm/linux/kernel/git/stable/l
|
|||||||
<a id='x1-39951r196'></a><span class='ecrm-0500'>196</span>
|
<a id='x1-39951r196'></a><span class='ecrm-0500'>196</span>
|
||||||
<a id='x1-39953r197'></a><span class='ecrm-0500'>197</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor1336'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span>
|
<a id='x1-39953r197'></a><span class='ecrm-0500'>197</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor1336'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span>
|
||||||
<a id='x1-39955r198'></a><span class='ecrm-0500'>198</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor1337'><span class='ectt-0800'>"This is test_ioctl module"</span></span><span class='ectt-0800'>);</span></pre>
|
<a id='x1-39955r198'></a><span class='ecrm-0500'>198</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor1337'><span class='ectt-0800'>"This is test_ioctl module"</span></span><span class='ectt-0800'>);</span></pre>
|
||||||
<!-- l. 1165 --><p class='noindent'>
|
<!-- l. 1164 --><p class='noindent'>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<h3 class='sectionHead' id='system-calls'><span class='titlemark'>0.10 </span> <a id='x1-400000.10'></a>System Calls</h3>
|
<h3 class='sectionHead' id='system-calls'><span class='titlemark'>0.10 </span> <a id='x1-400000.10'></a>System Calls</h3>
|
||||||
<!-- l. 1167 --><p class='noindent'>So far, the only thing we’ve done was to use well defined kernel mechanisms to
|
<!-- l. 1166 --><p class='noindent'>So far, the only thing we’ve done was to use well defined kernel mechanisms to
|
||||||
register <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>/proc</span></span></span> files and device handlers. This is fine if you want to do something the
|
register <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>/proc</span></span></span> files and device handlers. This is fine if you want to do something the
|
||||||
kernel programmers thought you’d want, such as write a device driver. But what if
|
kernel programmers thought you’d want, such as write a device driver. But what if
|
||||||
you want to do something unusual, to change the behavior of the system in some
|
you want to do something unusual, to change the behavior of the system in some
|
||||||
way? Then, you are mostly on your own.
|
way? Then, you are mostly on your own.
|
||||||
</p><!-- l. 1172 --><p class='indent'> If you are not being sensible and using a virtual machine then this is where kernel
|
</p><!-- l. 1171 --><p class='indent'> If you are not being sensible and using a virtual machine then this is where kernel
|
||||||
programming can become hazardous. While writing the example below, I killed the
|
programming can become hazardous. While writing the example below, I killed the
|
||||||
<code> <span class='ectt-1000'>open()</span>
|
<code> <span class='ectt-1000'>open()</span>
|
||||||
</code> system call. This meant I could not open any files, I could not run any
|
</code> system call. This meant I could not open any files, I could not run any
|
||||||
programs, and I could not shutdown the system. I had to restart the virtual
|
programs, and I could not shutdown the system. I had to restart the virtual
|
||||||
machine. No important files got anihilated, but if I was doing this on some live
|
machine. No important files got annihilated, but if I was doing this on some live
|
||||||
mission critical system then that could have been a possible outcome. To
|
mission critical system then that could have been a possible outcome. To
|
||||||
ensure you do not lose any files, even within a test environment, please run
|
ensure you do not lose any files, even within a test environment, please run
|
||||||
<code> <span class='ectt-1000'>sync</span>
|
<code> <span class='ectt-1000'>sync</span>
|
||||||
</code> right before you do the <code> <span class='ectt-1000'>insmod</span>
|
</code> right before you do the <code> <span class='ectt-1000'>insmod</span>
|
||||||
</code> and the <code> <span class='ectt-1000'>rmmod</span>
|
</code> and the <code> <span class='ectt-1000'>rmmod</span>
|
||||||
</code>.
|
</code>.
|
||||||
</p><!-- l. 1179 --><p class='indent'> Forget about <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>/proc</span></span></span> files, forget about device files. They are just minor details.
|
</p><!-- l. 1178 --><p class='indent'> Forget about <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>/proc</span></span></span> files, forget about device files. They are just minor details.
|
||||||
Minutiae in the vast expanse of the universe. The real process to kernel
|
Minutiae in the vast expanse of the universe. The real process to kernel
|
||||||
communication mechanism, the one used by all processes, is <span class='ecti-1000'>system calls</span>. When a
|
communication mechanism, the one used by all processes, is <span class='ecti-1000'>system calls</span>. When a
|
||||||
process requests a service from the kernel (such as opening a file, forking to a new
|
process requests a service from the kernel (such as opening a file, forking to a new
|
||||||
@ -2875,11 +2875,11 @@ change the behaviour of the kernel in interesting ways, this is the place to do
|
|||||||
it. By the way, if you want to see which system calls a program uses, run
|
it. By the way, if you want to see which system calls a program uses, run
|
||||||
<code> <span class='ectt-1000'>strace <arguments></span>
|
<code> <span class='ectt-1000'>strace <arguments></span>
|
||||||
</code>.
|
</code>.
|
||||||
</p><!-- l. 1187 --><p class='indent'> In general, a process is not supposed to be able to access the kernel. It can not
|
</p><!-- l. 1186 --><p class='indent'> In general, a process is not supposed to be able to access the kernel. It can not
|
||||||
access kernel memory and it can’t call kernel functions. The hardware of the CPU
|
access kernel memory and it can’t call kernel functions. The hardware of the CPU
|
||||||
enforces this (that is the reason why it is called “protected mode” or “page
|
enforces this (that is the reason why it is called “protected mode” or “page
|
||||||
protection”).
|
protection”).
|
||||||
</p><!-- l. 1191 --><p class='indent'> System calls are an exception to this general rule. What happens is that the
|
</p><!-- l. 1190 --><p class='indent'> System calls are an exception to this general rule. What happens is that the
|
||||||
process fills the registers with the appropriate values and then calls a special
|
process fills the registers with the appropriate values and then calls a special
|
||||||
instruction which jumps to a previously defined location in the kernel (of course, that
|
instruction which jumps to a previously defined location in the kernel (of course, that
|
||||||
location is readable by user processes, it is not writable by them). Under Intel CPUs,
|
location is readable by user processes, it is not writable by them). Under Intel CPUs,
|
||||||
@ -2887,7 +2887,7 @@ this is done by means of interrupt 0x80. The hardware knows that once you jump t
|
|||||||
this location, you are no longer running in restricted user mode, but as the
|
this location, you are no longer running in restricted user mode, but as the
|
||||||
operating system kernel — and therefore you’re allowed to do whatever you
|
operating system kernel — and therefore you’re allowed to do whatever you
|
||||||
want.
|
want.
|
||||||
</p><!-- l. 1196 --><p class='indent'> The location in the kernel a process can jump to is called <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>system_call</span></span></span>. The
|
</p><!-- l. 1195 --><p class='indent'> The location in the kernel a process can jump to is called <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>system_call</span></span></span>. The
|
||||||
procedure at that location checks the system call number, which tells the kernel what
|
procedure at that location checks the system call number, which tells the kernel what
|
||||||
service the process requested. Then, it looks at the table of system calls
|
service the process requested. Then, it looks at the table of system calls
|
||||||
(<code> <span class='ectt-1000'>sys_call_table</span>
|
(<code> <span class='ectt-1000'>sys_call_table</span>
|
||||||
@ -2900,7 +2900,7 @@ different process, if the process time ran out). If you want to read this code,
|
|||||||
at the source file <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>arch/$(architecture)/kernel/entry.S</span></span></span>, after the line
|
at the source file <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>arch/$(architecture)/kernel/entry.S</span></span></span>, after the line
|
||||||
<code> <span class='ectt-1000'>ENTRY(system_call)</span>
|
<code> <span class='ectt-1000'>ENTRY(system_call)</span>
|
||||||
</code>.
|
</code>.
|
||||||
</p><!-- l. 1202 --><p class='indent'> So, if we want to change the way a certain system call works, what we need to do
|
</p><!-- l. 1201 --><p class='indent'> So, if we want to change the way a certain system call works, what we need to do
|
||||||
is to write our own function to implement it (usually by adding a bit of our own
|
is to write our own function to implement it (usually by adding a bit of our own
|
||||||
code, and then calling the original function) and then change the pointer at
|
code, and then calling the original function) and then change the pointer at
|
||||||
<code> <span class='ectt-1000'>sys_call_table</span>
|
<code> <span class='ectt-1000'>sys_call_table</span>
|
||||||
@ -2908,7 +2908,7 @@ code, and then calling the original function) and then change the pointer at
|
|||||||
don’t want to leave the system in an unstable state, it’s important for
|
don’t want to leave the system in an unstable state, it’s important for
|
||||||
<code> <span class='ectt-1000'>cleanup_module</span>
|
<code> <span class='ectt-1000'>cleanup_module</span>
|
||||||
</code> to restore the table to its original state.
|
</code> to restore the table to its original state.
|
||||||
</p><!-- l. 1205 --><p class='indent'> The source code here is an example of such a kernel module. We want to “spy” on a certain
|
</p><!-- l. 1204 --><p class='indent'> The source code here is an example of such a kernel module. We want to “spy” on a certain
|
||||||
user, and to <code> <span class='ectt-1000'>pr_info()</span>
|
user, and to <code> <span class='ectt-1000'>pr_info()</span>
|
||||||
</code> a message whenever that user opens a file. Towards this end, we
|
</code> a message whenever that user opens a file. Towards this end, we
|
||||||
replace the system call to open a file with our own function, called
|
replace the system call to open a file with our own function, called
|
||||||
@ -2918,7 +2918,7 @@ spy on, it calls <code> <span class='ectt-1000'>pr_info()</span>
|
|||||||
</code> to display the name of the file to be opened. Then, either way, it calls the original
|
</code> to display the name of the file to be opened. Then, either way, it calls the original
|
||||||
<code> <span class='ectt-1000'>open()</span>
|
<code> <span class='ectt-1000'>open()</span>
|
||||||
</code> function with the same parameters, to actually open the file.
|
</code> function with the same parameters, to actually open the file.
|
||||||
</p><!-- l. 1211 --><p class='indent'> The <code> <span class='ectt-1000'>init_module</span>
|
</p><!-- l. 1210 --><p class='indent'> The <code> <span class='ectt-1000'>init_module</span>
|
||||||
</code> function replaces the appropriate location in
|
</code> function replaces the appropriate location in
|
||||||
<code> <span class='ectt-1000'>sys_call_table</span>
|
<code> <span class='ectt-1000'>sys_call_table</span>
|
||||||
</code> and keeps the original pointer in a variable. The
|
</code> and keeps the original pointer in a variable. The
|
||||||
@ -2936,7 +2936,7 @@ with <code> <span class='ectt-1000'>B_open</span>
|
|||||||
</code>, which will call what it thinks is the original system call,
|
</code>, which will call what it thinks is the original system call,
|
||||||
<code> <span class='ectt-1000'>A_open</span>
|
<code> <span class='ectt-1000'>A_open</span>
|
||||||
</code>, when it’s done.
|
</code>, when it’s done.
|
||||||
</p><!-- l. 1218 --><p class='indent'> Now, if B is removed first, everything will be well — it will simply restore the system
|
</p><!-- l. 1217 --><p class='indent'> Now, if B is removed first, everything will be well — it will simply restore the system
|
||||||
call to <code> <span class='ectt-1000'>A_open</span>
|
call to <code> <span class='ectt-1000'>A_open</span>
|
||||||
</code>, which calls the original. However, if A is removed and then B is removed, the
|
</code>, which calls the original. However, if A is removed and then B is removed, the
|
||||||
system will crash. A’s removal will restore the system call to the original,
|
system will crash. A’s removal will restore the system call to the original,
|
||||||
@ -2959,7 +2959,7 @@ problem. When A is removed, it sees that the system call was changed to
|
|||||||
</code> will still try to call <code> <span class='ectt-1000'>A_open</span>
|
</code> will still try to call <code> <span class='ectt-1000'>A_open</span>
|
||||||
</code> which is no longer there, so that even without removing B the system would
|
</code> which is no longer there, so that even without removing B the system would
|
||||||
crash.
|
crash.
|
||||||
</p><!-- l. 1226 --><p class='indent'> Note that all the related problems make syscall stealing unfeasiable for
|
</p><!-- l. 1225 --><p class='indent'> Note that all the related problems make syscall stealing unfeasible for
|
||||||
production use. In order to keep people from doing potential harmful things
|
production use. In order to keep people from doing potential harmful things
|
||||||
<code> <span class='ectt-1000'>sys_call_table</span>
|
<code> <span class='ectt-1000'>sys_call_table</span>
|
||||||
</code> is no longer exported. This means, if you want to do something more than a mere
|
</code> is no longer exported. This means, if you want to do something more than a mere
|
||||||
@ -2967,8 +2967,8 @@ dry run of this example, you will have to patch your current kernel in order to
|
|||||||
<code> <span class='ectt-1000'>sys_call_table</span>
|
<code> <span class='ectt-1000'>sys_call_table</span>
|
||||||
</code> exported. In the example directory you will find a README and the patch. As you
|
</code> exported. In the example directory you will find a README and the patch. As you
|
||||||
can imagine, such modifications are not to be taken lightly. Do not try this on
|
can imagine, such modifications are not to be taken lightly. Do not try this on
|
||||||
valueable systems (ie systems that you do not own - or cannot restore easily). You
|
valuable systems (ie systems that you do not own - or cannot restore easily). You will
|
||||||
will need to get the complete sourcecode of this guide as a tarball in order to get the
|
need to get the complete sourcecode of this guide as a tarball in order to get the
|
||||||
patch and the README. Depending on your kernel version, you might even need to
|
patch and the README. Depending on your kernel version, you might even need to
|
||||||
hand apply the patch.
|
hand apply the patch.
|
||||||
</p><!-- l. 1 --><p class='indent'>
|
</p><!-- l. 1 --><p class='indent'>
|
||||||
@ -3110,13 +3110,13 @@ hand apply the patch.
|
|||||||
<a id='x1-40302r135'></a><span class='ecrm-0500'>135</span><span class='ectt-0800'>module_exit(syscall_end);</span>
|
<a id='x1-40302r135'></a><span class='ecrm-0500'>135</span><span class='ectt-0800'>module_exit(syscall_end);</span>
|
||||||
<a id='x1-40304r136'></a><span class='ecrm-0500'>136</span>
|
<a id='x1-40304r136'></a><span class='ecrm-0500'>136</span>
|
||||||
<a id='x1-40306r137'></a><span class='ecrm-0500'>137</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor1471'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
<a id='x1-40306r137'></a><span class='ecrm-0500'>137</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor1471'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
||||||
<!-- l. 1237 --><p class='noindent'>
|
<!-- l. 1236 --><p class='noindent'>
|
||||||
</p>
|
</p>
|
||||||
<h3 class='sectionHead' id='blocking-processes-and-threads'><span class='titlemark'>0.11 </span> <a id='x1-410000.11'></a>Blocking Processes and threads</h3>
|
<h3 class='sectionHead' id='blocking-processes-and-threads'><span class='titlemark'>0.11 </span> <a id='x1-410000.11'></a>Blocking Processes and threads</h3>
|
||||||
<!-- l. 1239 --><p class='noindent'>
|
<!-- l. 1238 --><p class='noindent'>
|
||||||
</p>
|
</p>
|
||||||
<h4 class='subsectionHead' id='sleep'><span class='titlemark'>0.11.1 </span> <a id='x1-420000.11.1'></a>Sleep</h4>
|
<h4 class='subsectionHead' id='sleep'><span class='titlemark'>0.11.1 </span> <a id='x1-420000.11.1'></a>Sleep</h4>
|
||||||
<!-- l. 1241 --><p class='noindent'>What do you do when somebody asks you for something you can not do right
|
<!-- l. 1240 --><p class='noindent'>What do you do when somebody asks you for something you can not do right
|
||||||
away? If you are a human being and you are bothered by a human being, the
|
away? If you are a human being and you are bothered by a human being, the
|
||||||
only thing you can say is: "<span class='ecti-1000'>Not right now, I’m busy. Go away!</span>". But if you
|
only thing you can say is: "<span class='ecti-1000'>Not right now, I’m busy. Go away!</span>". But if you
|
||||||
are a kernel module and you are bothered by a process, you have another
|
are a kernel module and you are bothered by a process, you have another
|
||||||
@ -3127,21 +3127,21 @@ processes are being put to sleep by the kernel and woken up all the time (that
|
|||||||
|
|
||||||
is the way multiple processes appear to run on the same time on a single
|
is the way multiple processes appear to run on the same time on a single
|
||||||
CPU).
|
CPU).
|
||||||
</p><!-- l. 1247 --><p class='indent'> This kernel module is an example of this. The file (called <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>/proc/sleep</span></span></span>) can only
|
</p><!-- l. 1246 --><p class='indent'> This kernel module is an example of this. The file (called <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>/proc/sleep</span></span></span>) can only
|
||||||
be opened by a single process at a time. If the file is already open, the kernel module
|
be opened by a single process at a time. If the file is already open, the kernel module
|
||||||
calls <code> <span class='ectt-1000'>wait_event_interruptible</span>
|
calls <code> <span class='ectt-1000'>wait_event_interruptible</span>
|
||||||
</code>. The easiest way to keep a file open is to open it with:
|
</code>. The easiest way to keep a file open is to open it with:
|
||||||
</p><!-- l. 1 --><p class='indent'>
|
</p><!-- l. 1 --><p class='indent'>
|
||||||
</p>
|
</p>
|
||||||
<pre class='fancyvrb' id='fancyvrb53'><a id='x1-42004r1'></a><span class='ecrm-0500'>1</span><span class='ectt-1000'>tail -f</span></pre>
|
<pre class='fancyvrb' id='fancyvrb53'><a id='x1-42004r1'></a><span class='ecrm-0500'>1</span><span class='ectt-1000'>tail -f</span></pre>
|
||||||
<!-- l. 1256 --><p class='indent'> This function changes the status of the task (a task is the kernel data structure
|
<!-- l. 1255 --><p class='indent'> This function changes the status of the task (a task is the kernel data structure
|
||||||
which holds information about a process and the system call it is in, if any) to
|
which holds information about a process and the system call it is in, if any) to
|
||||||
<code> <span class='ectt-1000'>TASK_INTERRUPTIBLE</span>
|
<code> <span class='ectt-1000'>TASK_INTERRUPTIBLE</span>
|
||||||
</code>, which means that the task will not run until it is woken up somehow, and adds it to
|
</code>, which means that the task will not run until it is woken up somehow, and adds it to
|
||||||
WaitQ, the queue of tasks waiting to access the file. Then, the function calls the
|
WaitQ, the queue of tasks waiting to access the file. Then, the function calls the
|
||||||
scheduler to context switch to a different process, one which has some use for the
|
scheduler to context switch to a different process, one which has some use for the
|
||||||
CPU.
|
CPU.
|
||||||
</p><!-- l. 1260 --><p class='indent'> When a process is done with the file, it closes it, and
|
</p><!-- l. 1259 --><p class='indent'> When a process is done with the file, it closes it, and
|
||||||
<code> <span class='ectt-1000'>module_close</span>
|
<code> <span class='ectt-1000'>module_close</span>
|
||||||
</code> is called. That function wakes up all the processes in the queue (there’s no
|
</code> is called. That function wakes up all the processes in the queue (there’s no
|
||||||
mechanism to only wake up one of them). It then returns and the process which just
|
mechanism to only wake up one of them). It then returns and the process which just
|
||||||
@ -3151,20 +3151,20 @@ Eventually, one of the processes which was in the queue will be given control
|
|||||||
of the CPU by the scheduler. It starts at the point right after the call to
|
of the CPU by the scheduler. It starts at the point right after the call to
|
||||||
<code> <span class='ectt-1000'>module_interruptible_sleep_on</span>
|
<code> <span class='ectt-1000'>module_interruptible_sleep_on</span>
|
||||||
</code>.
|
</code>.
|
||||||
</p><!-- l. 1267 --><p class='indent'> This means that the process is still in kernel mode - as far as the process
|
</p><!-- l. 1266 --><p class='indent'> This means that the process is still in kernel mode - as far as the process
|
||||||
is concerned, it issued the open system call and the system call has not
|
is concerned, it issued the open system call and the system call has not
|
||||||
returned yet. The process does not know somebody else used the CPU for
|
returned yet. The process does not know somebody else used the CPU for
|
||||||
most of the time between the moment it issued the call and the moment it
|
most of the time between the moment it issued the call and the moment it
|
||||||
returned.
|
returned.
|
||||||
</p><!-- l. 1270 --><p class='indent'> It can then proceed to set a global variable to tell all the other processes that the
|
</p><!-- l. 1269 --><p class='indent'> It can then proceed to set a global variable to tell all the other processes that the
|
||||||
file is still open and go on with its life. When the other processes get a piece of the
|
file is still open and go on with its life. When the other processes get a piece of the
|
||||||
CPU, they’ll see that global variable and go back to sleep.
|
CPU, they’ll see that global variable and go back to sleep.
|
||||||
</p><!-- l. 1273 --><p class='indent'> So we will use <code> <span class='ectt-1000'>tail -f</span>
|
</p><!-- l. 1272 --><p class='indent'> So we will use <code> <span class='ectt-1000'>tail -f</span>
|
||||||
</code> to keep the file open in the background, while trying to access it with another
|
</code> to keep the file open in the background, while trying to access it with another
|
||||||
process (again in the background, so that we need not switch to a different vt). As
|
process (again in the background, so that we need not switch to a different vt). As
|
||||||
soon as the first background process is killed with kill %1 , the second is woken up, is
|
soon as the first background process is killed with kill %1 , the second is woken up, is
|
||||||
able to access the file and finally terminates.
|
able to access the file and finally terminates.
|
||||||
</p><!-- l. 1276 --><p class='indent'> To make our life more interesting, <code> <span class='ectt-1000'>module_close</span>
|
</p><!-- l. 1275 --><p class='indent'> To make our life more interesting, <code> <span class='ectt-1000'>module_close</span>
|
||||||
</code> does not have a monopoly on waking up the processes which wait to access the file.
|
</code> does not have a monopoly on waking up the processes which wait to access the file.
|
||||||
A signal, such as <span class='ecti-1000'>Ctrl +c </span>(<span class='ecbx-1000'>SIGINT</span>) can also wake up a process. This is because we
|
A signal, such as <span class='ecti-1000'>Ctrl +c </span>(<span class='ecbx-1000'>SIGINT</span>) can also wake up a process. This is because we
|
||||||
used <code> <span class='ectt-1000'>module_interruptible_sleep_on</span>
|
used <code> <span class='ectt-1000'>module_interruptible_sleep_on</span>
|
||||||
@ -3174,11 +3174,11 @@ used <code> <span class='ectt-1000'>module_interruptible_sleep_on</span>
|
|||||||
|
|
||||||
</code> instead, but that would have resulted in extremely angry users whose <span class='ecti-1000'>Ctrl+c</span>’s are
|
</code> instead, but that would have resulted in extremely angry users whose <span class='ecti-1000'>Ctrl+c</span>’s are
|
||||||
ignored.
|
ignored.
|
||||||
</p><!-- l. 1280 --><p class='indent'> In that case, we want to return with
|
</p><!-- l. 1279 --><p class='indent'> In that case, we want to return with
|
||||||
<code> <span class='ectt-1000'>-EINTR</span>
|
<code> <span class='ectt-1000'>-EINTR</span>
|
||||||
</code> immediately. This is important so users can, for example, kill the process before it
|
</code> immediately. This is important so users can, for example, kill the process before it
|
||||||
receives the file.
|
receives the file.
|
||||||
</p><!-- l. 1282 --><p class='indent'> There is one more point to remember. Some times processes don’t want to sleep, they want
|
</p><!-- l. 1281 --><p class='indent'> There is one more point to remember. Some times processes don’t want to sleep, they want
|
||||||
either to get what they want immediately, or to be told it cannot be done. Such processes
|
either to get what they want immediately, or to be told it cannot be done. Such processes
|
||||||
use the <code> <span class='ectt-1000'>O_NONBLOCK</span>
|
use the <code> <span class='ectt-1000'>O_NONBLOCK</span>
|
||||||
</code> flag when opening the file. The kernel is supposed to respond by returning with the error
|
</code> flag when opening the file. The kernel is supposed to respond by returning with the error
|
||||||
@ -3214,7 +3214,7 @@ $ cat_nonblock /proc/sleep
|
|||||||
Last input:
|
Last input:
|
||||||
$
|
$
|
||||||
</pre>
|
</pre>
|
||||||
<!-- l. 1307 --><p class='nopar'>
|
<!-- l. 1306 --><p class='nopar'>
|
||||||
</p><!-- l. 1 --><p class='indent'>
|
</p><!-- l. 1 --><p class='indent'>
|
||||||
</p>
|
</p>
|
||||||
<pre class='fancyvrb' id='fancyvrb54'><a id='x1-42018r1'></a><span class='ecrm-0500'>1</span><span id='textcolor1472'><span class='ectt-0800'>/*</span></span>
|
<pre class='fancyvrb' id='fancyvrb54'><a id='x1-42018r1'></a><span class='ecrm-0500'>1</span><span id='textcolor1472'><span class='ectt-0800'>/*</span></span>
|
||||||
@ -3498,14 +3498,14 @@ $
|
|||||||
<a id='x1-42568r57'></a><span class='ecrm-0500'>57</span>
|
<a id='x1-42568r57'></a><span class='ecrm-0500'>57</span>
|
||||||
<a id='x1-42570r58'></a><span class='ecrm-0500'>58</span><span class='ectt-0800'> </span><span id='textcolor1709'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> 0;</span>
|
<a id='x1-42570r58'></a><span class='ecrm-0500'>58</span><span class='ectt-0800'> </span><span id='textcolor1709'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> 0;</span>
|
||||||
<a id='x1-42572r59'></a><span class='ecrm-0500'>59</span><span class='ectt-0800'>}</span></pre>
|
<a id='x1-42572r59'></a><span class='ecrm-0500'>59</span><span class='ectt-0800'>}</span></pre>
|
||||||
<!-- l. 1313 --><p class='noindent'>
|
<!-- l. 1312 --><p class='noindent'>
|
||||||
</p>
|
</p>
|
||||||
<h4 class='subsectionHead' id='completions'><span class='titlemark'>0.11.2 </span> <a id='x1-430000.11.2'></a>Completions</h4>
|
<h4 class='subsectionHead' id='completions'><span class='titlemark'>0.11.2 </span> <a id='x1-430000.11.2'></a>Completions</h4>
|
||||||
<!-- l. 1315 --><p class='noindent'>Sometimes one thing should happen before another within a module having multiple threads.
|
<!-- l. 1314 --><p class='noindent'>Sometimes one thing should happen before another within a module having multiple threads.
|
||||||
Rather than using <code> <span class='ectt-1000'>/bin/sleep</span>
|
Rather than using <code> <span class='ectt-1000'>/bin/sleep</span>
|
||||||
</code> commands, the kernel has another way to do this which allows timeouts or
|
</code> commands, the kernel has another way to do this which allows timeouts or
|
||||||
interrupts to also happen.
|
interrupts to also happen.
|
||||||
</p><!-- l. 1318 --><p class='indent'> In the following example two threads are started, but one needs to start before
|
</p><!-- l. 1317 --><p class='indent'> In the following example two threads are started, but one needs to start before
|
||||||
another.
|
another.
|
||||||
</p><!-- l. 1 --><p class='indent'>
|
</p><!-- l. 1 --><p class='indent'>
|
||||||
|
|
||||||
@ -3588,31 +3588,31 @@ another.
|
|||||||
<a id='x1-43149r74'></a><span class='ecrm-0500'>74</span>
|
<a id='x1-43149r74'></a><span class='ecrm-0500'>74</span>
|
||||||
<a id='x1-43151r75'></a><span class='ecrm-0500'>75</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor1760'><span class='ectt-0800'>"Completions example"</span></span><span class='ectt-0800'>);</span>
|
<a id='x1-43151r75'></a><span class='ecrm-0500'>75</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor1760'><span class='ectt-0800'>"Completions example"</span></span><span class='ectt-0800'>);</span>
|
||||||
<a id='x1-43153r76'></a><span class='ecrm-0500'>76</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor1761'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
<a id='x1-43153r76'></a><span class='ecrm-0500'>76</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor1761'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
||||||
<!-- l. 1322 --><p class='indent'> The <code> <span class='ectt-1000'>machine</span>
|
<!-- l. 1321 --><p class='indent'> The <code> <span class='ectt-1000'>machine</span>
|
||||||
</code> structure stores the completion states for the two threads. At the exit
|
</code> structure stores the completion states for the two threads. At the exit
|
||||||
point of each thread the respective completion state is updated, and
|
point of each thread the respective completion state is updated, and
|
||||||
<code> <span class='ectt-1000'>wait_for_completion</span>
|
<code> <span class='ectt-1000'>wait_for_completion</span>
|
||||||
</code> is used by the flywheel thread to ensure that it does not begin prematurely.
|
</code> is used by the flywheel thread to ensure that it does not begin prematurely.
|
||||||
</p><!-- l. 1325 --><p class='indent'> So even though <code> <span class='ectt-1000'>flywheel_thread</span>
|
</p><!-- l. 1324 --><p class='indent'> So even though <code> <span class='ectt-1000'>flywheel_thread</span>
|
||||||
</code> is started first you should notice if you load this module and run
|
</code> is started first you should notice if you load this module and run
|
||||||
<code> <span class='ectt-1000'>dmesg</span>
|
<code> <span class='ectt-1000'>dmesg</span>
|
||||||
</code> that turning the crank always happens first because the flywheel thread waits for it
|
</code> that turning the crank always happens first because the flywheel thread waits for it
|
||||||
to complete.
|
to complete.
|
||||||
</p><!-- l. 1327 --><p class='indent'> There are other variations upon the
|
</p><!-- l. 1326 --><p class='indent'> There are other variations upon the
|
||||||
<code> <span class='ectt-1000'>wait_for_completion</span>
|
<code> <span class='ectt-1000'>wait_for_completion</span>
|
||||||
</code> function, which include timeouts or being interrupted, but this basic mechanism is
|
</code> function, which include timeouts or being interrupted, but this basic mechanism is
|
||||||
enough for many common situations without adding a lot of complexity.
|
enough for many common situations without adding a lot of complexity.
|
||||||
</p><!-- l. 1329 --><p class='noindent'>
|
</p><!-- l. 1328 --><p class='noindent'>
|
||||||
</p>
|
</p>
|
||||||
<h3 class='sectionHead' id='avoiding-collisions-and-deadlocks'><span class='titlemark'>0.12 </span> <a id='x1-440000.12'></a>Avoiding Collisions and Deadlocks</h3>
|
<h3 class='sectionHead' id='avoiding-collisions-and-deadlocks'><span class='titlemark'>0.12 </span> <a id='x1-440000.12'></a>Avoiding Collisions and Deadlocks</h3>
|
||||||
<!-- l. 1331 --><p class='noindent'>If processes running on different CPUs or in different threads try to access the same
|
<!-- l. 1330 --><p class='noindent'>If processes running on different CPUs or in different threads try to access the same
|
||||||
memory, then it is possible that strange things can happen or your system can lock
|
memory, then it is possible that strange things can happen or your system can lock
|
||||||
up. To avoid this, various types of mutual exclusion kernel functions are available.
|
up. To avoid this, various types of mutual exclusion kernel functions are available.
|
||||||
These indicate if a section of code is "locked" or "unlocked" so that simultaneous
|
These indicate if a section of code is "locked" or "unlocked" so that simultaneous
|
||||||
attempts to run it can not happen.
|
attempts to run it can not happen.
|
||||||
</p>
|
</p>
|
||||||
<h4 class='subsectionHead' id='mutex'><span class='titlemark'>0.12.1 </span> <a id='x1-450000.12.1'></a>Mutex</h4>
|
<h4 class='subsectionHead' id='mutex'><span class='titlemark'>0.12.1 </span> <a id='x1-450000.12.1'></a>Mutex</h4>
|
||||||
<!-- l. 1336 --><p class='noindent'>You can use kernel mutexes (mutual exclusions) in much the same manner that you
|
<!-- l. 1335 --><p class='noindent'>You can use kernel mutexes (mutual exclusions) in much the same manner that you
|
||||||
might deploy them in userland. This may be all that is needed to avoid collisions in
|
might deploy them in userland. This may be all that is needed to avoid collisions in
|
||||||
most cases.
|
most cases.
|
||||||
</p><!-- l. 1 --><p class='indent'>
|
</p><!-- l. 1 --><p class='indent'>
|
||||||
@ -3658,18 +3658,18 @@ most cases.
|
|||||||
<a id='x1-45078r39'></a><span class='ecrm-0500'>39</span>
|
<a id='x1-45078r39'></a><span class='ecrm-0500'>39</span>
|
||||||
<a id='x1-45080r40'></a><span class='ecrm-0500'>40</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor1802'><span class='ectt-0800'>"Mutex example"</span></span><span class='ectt-0800'>);</span>
|
<a id='x1-45080r40'></a><span class='ecrm-0500'>40</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor1802'><span class='ectt-0800'>"Mutex example"</span></span><span class='ectt-0800'>);</span>
|
||||||
<a id='x1-45082r41'></a><span class='ecrm-0500'>41</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor1803'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
<a id='x1-45082r41'></a><span class='ecrm-0500'>41</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor1803'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
||||||
<!-- l. 1341 --><p class='noindent'>
|
<!-- l. 1340 --><p class='noindent'>
|
||||||
</p>
|
</p>
|
||||||
<h4 class='subsectionHead' id='spinlocks'><span class='titlemark'>0.12.2 </span> <a id='x1-460000.12.2'></a>Spinlocks</h4>
|
<h4 class='subsectionHead' id='spinlocks'><span class='titlemark'>0.12.2 </span> <a id='x1-460000.12.2'></a>Spinlocks</h4>
|
||||||
<!-- l. 1343 --><p class='noindent'>As the name suggests, spinlocks lock up the CPU that the code is running on,
|
<!-- l. 1342 --><p class='noindent'>As the name suggests, spinlocks lock up the CPU that the code is running on,
|
||||||
taking 100% of its resources. Because of this you should only use the spinlock
|
taking 100% of its resources. Because of this you should only use the spinlock
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
mechanism around code which is likely to take no more than a few milliseconds to
|
mechanism around code which is likely to take no more than a few milliseconds to
|
||||||
run and so will not noticably slow anything down from the user’s point of
|
run and so will not noticeably slow anything down from the user’s point of
|
||||||
view.
|
view.
|
||||||
</p><!-- l. 1346 --><p class='indent'> The example here is <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>"irq safe"</span></span></span> in that if interrupts happen during the lock then
|
</p><!-- l. 1345 --><p class='indent'> The example here is <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>"irq safe"</span></span></span> in that if interrupts happen during the lock then
|
||||||
they will not be forgotten and will activate when the unlock happens, using the
|
they will not be forgotten and will activate when the unlock happens, using the
|
||||||
<code> <span class='ectt-1000'>flags</span>
|
<code> <span class='ectt-1000'>flags</span>
|
||||||
</code> variable to retain their state.
|
</code> variable to retain their state.
|
||||||
@ -3738,10 +3738,10 @@ they will not be forgotten and will activate when the unlock happens, using the
|
|||||||
<a id='x1-46123r61'></a><span class='ecrm-0500'>61</span>
|
<a id='x1-46123r61'></a><span class='ecrm-0500'>61</span>
|
||||||
<a id='x1-46125r62'></a><span class='ecrm-0500'>62</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor1858'><span class='ectt-0800'>"Spinlock example"</span></span><span class='ectt-0800'>);</span>
|
<a id='x1-46125r62'></a><span class='ecrm-0500'>62</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor1858'><span class='ectt-0800'>"Spinlock example"</span></span><span class='ectt-0800'>);</span>
|
||||||
<a id='x1-46127r63'></a><span class='ecrm-0500'>63</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor1859'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
<a id='x1-46127r63'></a><span class='ecrm-0500'>63</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor1859'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
||||||
<!-- l. 1350 --><p class='noindent'>
|
<!-- l. 1349 --><p class='noindent'>
|
||||||
</p>
|
</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>
|
<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. 1352 --><p class='noindent'>Read and write locks are specialised kinds of spinlocks so that you can exclusively
|
<!-- 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
|
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
|
from irqs which might also read and write to whatever you are concerned with
|
||||||
@ -3806,14 +3806,14 @@ module.
|
|||||||
<a id='x1-47106r53'></a><span class='ecrm-0500'>53</span>
|
<a id='x1-47106r53'></a><span class='ecrm-0500'>53</span>
|
||||||
<a id='x1-47108r54'></a><span class='ecrm-0500'>54</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor1906'><span class='ectt-0800'>"Read/Write locks example"</span></span><span class='ectt-0800'>);</span>
|
<a id='x1-47108r54'></a><span class='ecrm-0500'>54</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor1906'><span class='ectt-0800'>"Read/Write locks example"</span></span><span class='ectt-0800'>);</span>
|
||||||
<a id='x1-47110r55'></a><span class='ecrm-0500'>55</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor1907'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
<a id='x1-47110r55'></a><span class='ecrm-0500'>55</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor1907'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
||||||
<!-- l. 1358 --><p class='indent'> Of course, if you know for sure that there are no functions triggered by irqs
|
<!-- l. 1357 --><p class='indent'> Of course, if you know for sure that there are no functions triggered by irqs
|
||||||
which could possibly interfere with your logic then you can use the simpler
|
which could possibly interfere with your logic then you can use the simpler
|
||||||
<code> <span class='ectt-1000'>read_lock(&myrwlock)</span>
|
<code> <span class='ectt-1000'>read_lock(&myrwlock)</span>
|
||||||
</code> and <code> <span class='ectt-1000'>read_unlock(&myrwlock)</span>
|
</code> and <code> <span class='ectt-1000'>read_unlock(&myrwlock)</span>
|
||||||
</code> or the corresponding write functions.
|
</code> or the corresponding write functions.
|
||||||
</p>
|
</p>
|
||||||
<h4 class='subsectionHead' id='atomic-operations'><span class='titlemark'>0.12.4 </span> <a id='x1-480000.12.4'></a>Atomic operations</h4>
|
<h4 class='subsectionHead' id='atomic-operations'><span class='titlemark'>0.12.4 </span> <a id='x1-480000.12.4'></a>Atomic operations</h4>
|
||||||
<!-- l. 1361 --><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
|
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
|
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
|
can be confident that your addition, subtraction or bit flip did actually happen
|
||||||
@ -3898,21 +3898,21 @@ below.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- l. 1368 --><p class='noindent'>
|
<!-- l. 1367 --><p class='noindent'>
|
||||||
</p>
|
</p>
|
||||||
<h3 class='sectionHead' id='replacing-print-macros'><span class='titlemark'>0.13 </span> <a id='x1-490000.13'></a>Replacing Print Macros</h3>
|
<h3 class='sectionHead' id='replacing-print-macros'><span class='titlemark'>0.13 </span> <a id='x1-490000.13'></a>Replacing Print Macros</h3>
|
||||||
<!-- l. 1370 --><p class='noindent'>
|
<!-- l. 1369 --><p class='noindent'>
|
||||||
</p>
|
</p>
|
||||||
<h4 class='subsectionHead' id='replacement'><span class='titlemark'>0.13.1 </span> <a id='x1-500000.13.1'></a>Replacement</h4>
|
<h4 class='subsectionHead' id='replacement'><span class='titlemark'>0.13.1 </span> <a id='x1-500000.13.1'></a>Replacement</h4>
|
||||||
<!-- l. 1372 --><p class='noindent'>In Section <a href='#x1-80042'>2<!-- tex4ht:ref: sec:using_x --></a>, I said that X Window System and kernel module programming do not
|
<!-- l. 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
|
able to send messages to whichever tty the command to load the module came
|
||||||
from.
|
from.
|
||||||
</p><!-- l. 1376 --><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
|
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
|
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.
|
display, a network connection used with ssh, etc.
|
||||||
</p><!-- l. 1378 --><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
|
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
|
a pointer to a string write function, which we use to write a string to the
|
||||||
tty.
|
tty.
|
||||||
@ -3995,16 +3995,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-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-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='textcolor2032'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
<a id='x1-50154r77'></a><span class='ecrm-0500'>77</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor2032'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
||||||
<!-- l. 1383 --><p class='noindent'>
|
<!-- l. 1382 --><p class='noindent'>
|
||||||
</p>
|
</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>
|
<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. 1385 --><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
|
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
|
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,
|
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
|
and their use is rather simple and non-intrusive, compared to writing to a tty or a
|
||||||
file.
|
file.
|
||||||
</p><!-- l. 1389 --><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.
|
loaded, starts blinking the keyboard LEDs until it is unloaded.
|
||||||
</p><!-- l. 1 --><p class='indent'>
|
</p><!-- l. 1 --><p class='indent'>
|
||||||
</p>
|
</p>
|
||||||
@ -4100,7 +4100,7 @@ loaded, starts blinking the keyboard LEDs until it is unloaded.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- l. 1393 --><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
|
there might yet be some other tricks to try. Ever wondered what
|
||||||
<code> <span class='ectt-1000'>CONFIG_LL_DEBUG</span>
|
<code> <span class='ectt-1000'>CONFIG_LL_DEBUG</span>
|
||||||
</code> in <code> <span class='ectt-1000'>make menuconfig</span>
|
</code> in <code> <span class='ectt-1000'>make menuconfig</span>
|
||||||
@ -4111,22 +4111,22 @@ everything what your code does over a serial line. If you find yourself porting
|
|||||||
kernel to some new and former unsupported architecture, this is usually amongst the
|
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
|
first things that should be implemented. Logging over a netconsole might also be
|
||||||
worth a try.
|
worth a try.
|
||||||
</p><!-- l. 1400 --><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
|
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
|
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
|
should try to keep debug code to a minimum and make sure it does not show up in
|
||||||
production code.
|
production code.
|
||||||
</p><!-- l. 1404 --><p class='noindent'>
|
</p><!-- l. 1403 --><p class='noindent'>
|
||||||
</p>
|
</p>
|
||||||
<h3 class='sectionHead' id='scheduling-tasks'><span class='titlemark'>0.14 </span> <a id='x1-520000.14'></a>Scheduling Tasks</h3>
|
<h3 class='sectionHead' id='scheduling-tasks'><span class='titlemark'>0.14 </span> <a id='x1-520000.14'></a>Scheduling Tasks</h3>
|
||||||
<!-- l. 1406 --><p class='noindent'>There are two main ways of running tasks: tasklets and work queues. Tasklets are a
|
<!-- 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
|
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
|
triggered from an interrupt, whereas work queues are more complicated but also
|
||||||
better suited to running multiple things in a sequence.
|
better suited to running multiple things in a sequence.
|
||||||
</p><!-- l. 1410 --><p class='noindent'>
|
</p><!-- l. 1409 --><p class='noindent'>
|
||||||
</p>
|
</p>
|
||||||
<h4 class='subsectionHead' id='tasklets'><span class='titlemark'>0.14.1 </span> <a id='x1-530000.14.1'></a>Tasklets</h4>
|
<h4 class='subsectionHead' id='tasklets'><span class='titlemark'>0.14.1 </span> <a id='x1-530000.14.1'></a>Tasklets</h4>
|
||||||
<!-- l. 1412 --><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> <span class='ectt-1000'>tasklet_fn</span>
|
||||||
</code> function runs for a few seconds and in the mean time execution of the
|
</code> function runs for a few seconds and in the mean time execution of the
|
||||||
<code> <span class='ectt-1000'>example_tasklet_init</span>
|
<code> <span class='ectt-1000'>example_tasklet_init</span>
|
||||||
@ -4170,7 +4170,7 @@ better suited to running multiple things in a sequence.
|
|||||||
<a id='x1-53072r35'></a><span class='ecrm-0500'>35</span>
|
<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='textcolor2152'><span class='ectt-0800'>"Tasklet example"</span></span><span class='ectt-0800'>);</span>
|
<a id='x1-53074r36'></a><span class='ecrm-0500'>36</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor2152'><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='textcolor2153'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
<a id='x1-53076r37'></a><span class='ecrm-0500'>37</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor2153'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
||||||
<!-- l. 1417 --><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:
|
</code> should show:
|
||||||
|
|
||||||
|
|
||||||
@ -4182,11 +4182,11 @@ Example tasklet starts
|
|||||||
Example tasklet init continues...
|
Example tasklet init continues...
|
||||||
Example tasklet ends
|
Example tasklet ends
|
||||||
</pre>
|
</pre>
|
||||||
<!-- l. 1424 --><p class='nopar'>
|
<!-- l. 1423 --><p class='nopar'>
|
||||||
</p><!-- l. 1426 --><p class='noindent'>
|
</p><!-- l. 1425 --><p class='noindent'>
|
||||||
</p>
|
</p>
|
||||||
<h4 class='subsectionHead' id='work-queues'><span class='titlemark'>0.14.2 </span> <a id='x1-540000.14.2'></a>Work queues</h4>
|
<h4 class='subsectionHead' id='work-queues'><span class='titlemark'>0.14.2 </span> <a id='x1-540000.14.2'></a>Work queues</h4>
|
||||||
<!-- l. 1428 --><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.
|
Completely Fair Scheduler (CFS) to execute work within the queue.
|
||||||
</p><!-- l. 1 --><p class='indent'>
|
</p><!-- l. 1 --><p class='indent'>
|
||||||
</p>
|
</p>
|
||||||
@ -4224,19 +4224,19 @@ Completely Fair Scheduler (CFS) to execute work within the queue.
|
|||||||
<a id='x1-54064r32'></a><span class='ecrm-0500'>32</span>
|
<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='textcolor2181'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span>
|
<a id='x1-54066r33'></a><span class='ecrm-0500'>33</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor2181'><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='textcolor2182'><span class='ectt-0800'>"Workqueue example"</span></span><span class='ectt-0800'>);</span></pre>
|
<a id='x1-54068r34'></a><span class='ecrm-0500'>34</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor2182'><span class='ectt-0800'>"Workqueue example"</span></span><span class='ectt-0800'>);</span></pre>
|
||||||
<!-- l. 1433 --><p class='noindent'>
|
<!-- l. 1432 --><p class='noindent'>
|
||||||
</p>
|
</p>
|
||||||
<h3 class='sectionHead' id='interrupt-handlers'><span class='titlemark'>0.15 </span> <a id='x1-550000.15'></a>Interrupt Handlers</h3>
|
<h3 class='sectionHead' id='interrupt-handlers'><span class='titlemark'>0.15 </span> <a id='x1-550000.15'></a>Interrupt Handlers</h3>
|
||||||
<!-- l. 1435 --><p class='noindent'>
|
<!-- l. 1434 --><p class='noindent'>
|
||||||
</p>
|
</p>
|
||||||
<h4 class='subsectionHead' id='interrupt-handlers1'><span class='titlemark'>0.15.1 </span> <a id='x1-560000.15.1'></a>Interrupt Handlers</h4>
|
<h4 class='subsectionHead' id='interrupt-handlers1'><span class='titlemark'>0.15.1 </span> <a id='x1-560000.15.1'></a>Interrupt Handlers</h4>
|
||||||
<!-- l. 1437 --><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
|
response to a process asking for it, either by dealing with a special file, sending an
|
||||||
<code> <span class='ectt-1000'>ioctl()</span>
|
<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
|
</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
|
requests. Another job, which is every bit as important, is to speak to the hardware
|
||||||
connected to the machine.
|
connected to the machine.
|
||||||
</p><!-- l. 1441 --><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,
|
computer’s hardware. The first type is when the CPU gives orders to the hardware,
|
||||||
the order is when the hardware needs to tell the CPU something. The second, called
|
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
|
interrupts, is much harder to implement because it has to be dealt with when
|
||||||
@ -4246,14 +4246,14 @@ lost.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
</p><!-- l. 1446 --><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
|
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
|
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
|
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
|
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
|
device). If at all possible, it is better to declare an interrupt handler to be
|
||||||
long.
|
long.
|
||||||
</p><!-- l. 1452 --><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
|
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
|
only when the more important one is done), saves certain parameters on
|
||||||
the stack and calls the interrupt handler. This means that certain things
|
the stack and calls the interrupt handler. This means that certain things
|
||||||
@ -4265,10 +4265,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
|
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
|
possible – and when it does, everything allowed in kernel modules will be
|
||||||
allowed.
|
allowed.
|
||||||
</p><!-- l. 1458 --><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> <span class='ectt-1000'>request_irq()</span>
|
||||||
</code> to get your interrupt handler called when the relevant IRQ is received.
|
</code> to get your interrupt handler called when the relevant IRQ is received.
|
||||||
</p><!-- l. 1460 --><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
|
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
|
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
|
controller A. Of course, that requires that the kernel finds out which IRQ it
|
||||||
@ -4278,11 +4278,11 @@ them requires handlers to be written in assembler, so they do not really
|
|||||||
fit into the kernel. They can be made to work similar to the others, but
|
fit into the kernel. They can be made to work similar to the others, but
|
||||||
after that procedure, they are no longer any faster than "common" IRQs.
|
after that procedure, they are no longer any faster than "common" IRQs.
|
||||||
SMP enabled kernels running on systems with more than one processor
|
SMP enabled kernels running on systems with more than one processor
|
||||||
need to solve another truckload of problems. It is not enough to know if
|
need to solve another truckload of problems. It is not enough to know if a
|
||||||
a certain IRQs has happend, it’s also important for what CPU(s) it was
|
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"
|
for. People still interested in more details, might want to refer to "APIC"
|
||||||
now.
|
now.
|
||||||
</p><!-- l. 1469 --><p class='indent'> This function receives the IRQ number, the name of the function,
|
</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
|
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.
|
interrupt handler. Usually there is a certain number of IRQs available.
|
||||||
How many IRQs there are is hardware-dependent. The flags can include
|
How many IRQs there are is hardware-dependent. The flags can include
|
||||||
@ -4295,16 +4295,16 @@ already a handler on this IRQ, or if you are both willing to share.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
</p><!-- l. 1475 --><p class='noindent'>
|
</p><!-- l. 1474 --><p class='noindent'>
|
||||||
</p>
|
</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>
|
<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. 1477 --><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
|
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
|
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
|
it is better for the input to trigger the CPU to then run a particular handling
|
||||||
function.
|
function.
|
||||||
</p><!-- l. 1481 --><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
|
an LED is connected to GPIO 4. You can change those numbers to whatever is
|
||||||
appropriate for your board.
|
appropriate for your board.
|
||||||
</p><!-- l. 1 --><p class='indent'>
|
</p><!-- l. 1 --><p class='indent'>
|
||||||
@ -4454,14 +4454,14 @@ appropriate for your board.
|
|||||||
<a id='x1-57286r143'></a><span class='ecrm-0500'>143</span>
|
<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='textcolor2289'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span>
|
<a id='x1-57288r144'></a><span class='ecrm-0500'>144</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor2289'><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='textcolor2290'><span class='ectt-0800'>"Handle some GPIO interrupts"</span></span><span class='ectt-0800'>);</span></pre>
|
<a id='x1-57290r145'></a><span class='ecrm-0500'>145</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor2290'><span class='ectt-0800'>"Handle some GPIO interrupts"</span></span><span class='ectt-0800'>);</span></pre>
|
||||||
<!-- l. 1486 --><p class='noindent'>
|
<!-- l. 1485 --><p class='noindent'>
|
||||||
</p>
|
</p>
|
||||||
<h4 class='subsectionHead' id='bottom-half'><span class='titlemark'>0.15.3 </span> <a id='x1-580000.15.3'></a>Bottom Half</h4>
|
<h4 class='subsectionHead' id='bottom-half'><span class='titlemark'>0.15.3 </span> <a id='x1-580000.15.3'></a>Bottom Half</h4>
|
||||||
<!-- l. 1488 --><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
|
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
|
is to combine it with a tasklet. This pushes the bulk of the work off into the
|
||||||
scheduler.
|
scheduler.
|
||||||
</p><!-- l. 1492 --><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.
|
when an interrupt is triggered.
|
||||||
</p><!-- l. 1 --><p class='indent'>
|
</p><!-- l. 1 --><p class='indent'>
|
||||||
</p>
|
</p>
|
||||||
@ -4626,10 +4626,10 @@ when an interrupt is triggered.
|
|||||||
<a id='x1-58318r159'></a><span class='ecrm-0500'>159</span>
|
<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='textcolor2411'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span>
|
<a id='x1-58320r160'></a><span class='ecrm-0500'>160</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor2411'><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='textcolor2412'><span class='ectt-0800'>"Interrupt with top and bottom half"</span></span><span class='ectt-0800'>);</span></pre>
|
<a id='x1-58322r161'></a><span class='ecrm-0500'>161</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor2412'><span class='ectt-0800'>"Interrupt with top and bottom half"</span></span><span class='ectt-0800'>);</span></pre>
|
||||||
<!-- l. 1496 --><p class='noindent'>
|
<!-- l. 1495 --><p class='noindent'>
|
||||||
</p>
|
</p>
|
||||||
<h3 class='sectionHead' id='crypto'><span class='titlemark'>0.16 </span> <a id='x1-590000.16'></a>Crypto</h3>
|
<h3 class='sectionHead' id='crypto'><span class='titlemark'>0.16 </span> <a id='x1-590000.16'></a>Crypto</h3>
|
||||||
<!-- l. 1498 --><p class='noindent'>At the dawn of the internet, everybody trusted everybody completely…but that did
|
<!-- 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
|
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
|
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
|
||||||
@ -4638,10 +4638,10 @@ favourite hash functions.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
</p><!-- l. 1503 --><p class='noindent'>
|
</p><!-- l. 1502 --><p class='noindent'>
|
||||||
</p>
|
</p>
|
||||||
<h4 class='subsectionHead' id='hash-functions'><span class='titlemark'>0.16.1 </span> <a id='x1-600000.16.1'></a>Hash functions</h4>
|
<h4 class='subsectionHead' id='hash-functions'><span class='titlemark'>0.16.1 </span> <a id='x1-600000.16.1'></a>Hash functions</h4>
|
||||||
<!-- l. 1506 --><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.
|
demonstration of how to calculate a sha256 hash within a kernel module.
|
||||||
</p><!-- l. 1 --><p class='indent'>
|
</p><!-- l. 1 --><p class='indent'>
|
||||||
</p>
|
</p>
|
||||||
@ -4707,21 +4707,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-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='textcolor2462'><span class='ectt-0800'>"sha256 hash test"</span></span><span class='ectt-0800'>);</span>
|
<a id='x1-60122r61'></a><span class='ecrm-0500'>61</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor2462'><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='textcolor2463'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
<a id='x1-60124r62'></a><span class='ecrm-0500'>62</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor2463'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
||||||
<!-- l. 1511 --><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><!-- l. 1 --><p class='indent'>
|
||||||
</p>
|
</p>
|
||||||
<pre class='fancyvrb' id='fancyvrb68'><a id='x1-60129r1'></a><span class='ecrm-0500'>1</span><span class='ectt-1000'>make</span>
|
<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-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>
|
<a id='x1-60133r3'></a><span class='ecrm-0500'>3</span><span class='ectt-1000'>dmesg</span></pre>
|
||||||
<!-- l. 1519 --><p class='indent'> And you should see that the hash was calculated for the test string.
|
<!-- l. 1518 --><p class='indent'> And you should see that the hash was calculated for the test string.
|
||||||
</p><!-- l. 1521 --><p class='indent'> Finally, remove the test module:
|
</p><!-- l. 1520 --><p class='indent'> Finally, remove the test module:
|
||||||
</p><!-- l. 1 --><p class='indent'>
|
</p><!-- l. 1 --><p class='indent'>
|
||||||
</p>
|
</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>
|
<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. 1527 --><p class='noindent'>
|
<!-- l. 1526 --><p class='noindent'>
|
||||||
</p>
|
</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>
|
<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. 1529 --><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.
|
and a password.
|
||||||
</p><!-- l. 1 --><p class='indent'>
|
</p><!-- l. 1 --><p class='indent'>
|
||||||
</p>
|
</p>
|
||||||
@ -4922,13 +4922,13 @@ and a password.
|
|||||||
<a id='x1-61390r195'></a><span class='ecrm-0500'>195</span>
|
<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='textcolor2609'><span class='ectt-0800'>"Symmetric key encryption example"</span></span><span class='ectt-0800'>);</span>
|
<a id='x1-61392r196'></a><span class='ecrm-0500'>196</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor2609'><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='textcolor2610'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
<a id='x1-61394r197'></a><span class='ecrm-0500'>197</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor2610'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
||||||
<!-- l. 1533 --><p class='noindent'>
|
<!-- l. 1532 --><p class='noindent'>
|
||||||
</p>
|
</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>
|
<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. 1535 --><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
|
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
|
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
|
resume a device a device model was added. An example is shown below, and you can
|
||||||
use this as a template to add your own suspend, resume or other interface
|
use this as a template to add your own suspend, resume or other interface
|
||||||
functions.
|
functions.
|
||||||
</p><!-- l. 1 --><p class='indent'>
|
</p><!-- l. 1 --><p class='indent'>
|
||||||
@ -5035,24 +5035,23 @@ functions.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- l. 1541 --><p class='noindent'>
|
<!-- l. 1540 --><p class='noindent'>
|
||||||
</p>
|
</p>
|
||||||
<h3 class='sectionHead' id='optimizations'><span class='titlemark'>0.18 </span> <a id='x1-630000.18'></a>Optimizations</h3>
|
<h3 class='sectionHead' id='optimizations'><span class='titlemark'>0.18 </span> <a id='x1-630000.18'></a>Optimizations</h3>
|
||||||
<!-- l. 1543 --><p class='noindent'>
|
<!-- l. 1542 --><p class='noindent'>
|
||||||
</p>
|
</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>
|
<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. 1545 --><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
|
especially if it is handling an interrupt or doing something which might
|
||||||
cause noticible latency. If your code contains boolean conditions and if you
|
cause noticeable latency. If your code contains boolean conditions and if
|
||||||
know that the conditions are almost always likely to evaluate as either
|
you know that the conditions are almost always likely to evaluate as either
|
||||||
<code> <span class='ectt-1000'>true</span>
|
<code> <span class='ectt-1000'>true</span>
|
||||||
</code> or <code> <span class='ectt-1000'>false</span>
|
</code> or <code> <span class='ectt-1000'>false</span>
|
||||||
</code>, then you can allow the compiler to optimize for this using the
|
</code>, then you can allow the compiler to optimize for this using the
|
||||||
<code> <span class='ectt-1000'>likely</span>
|
<code> <span class='ectt-1000'>likely</span>
|
||||||
</code> and <code> <span class='ectt-1000'>unlikely</span>
|
</code> and <code> <span class='ectt-1000'>unlikely</span>
|
||||||
</code> macros.
|
</code> macros. For example, when allocating memory you are almost always expecting this
|
||||||
</p><!-- l. 1549 --><p class='indent'> For example, when allocating memory you are almost always expecting this to
|
to succeed.
|
||||||
succeed.
|
|
||||||
</p><!-- l. 1 --><p class='indent'>
|
</p><!-- l. 1 --><p class='indent'>
|
||||||
</p>
|
</p>
|
||||||
<pre class='fancyvrb' id='fancyvrb72'><a id='x1-64012r1'></a><span class='ecrm-0500'>1</span><span class='ectt-0800'>bvl = bvec_alloc(gfp_mask, nr_iovecs, &idx);</span>
|
<pre class='fancyvrb' id='fancyvrb72'><a id='x1-64012r1'></a><span class='ecrm-0500'>1</span><span class='ectt-0800'>bvl = bvec_alloc(gfp_mask, nr_iovecs, &idx);</span>
|
||||||
@ -5061,50 +5060,50 @@ succeed.
|
|||||||
<a id='x1-64018r4'></a><span class='ecrm-0500'>4</span><span class='ectt-0800'> bio = NULL;</span>
|
<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='textcolor2688'><span class='ectt-0800'>goto</span></span><span class='ectt-0800'> out;</span>
|
<a id='x1-64020r5'></a><span class='ecrm-0500'>5</span><span class='ectt-0800'> </span><span id='textcolor2688'><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>
|
<a id='x1-64022r6'></a><span class='ecrm-0500'>6</span><span class='ectt-0800'>}</span></pre>
|
||||||
<!-- l. 1560 --><p class='indent'> When the <code> <span class='ectt-1000'>unlikely</span>
|
<!-- l. 1558 --><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
|
</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
|
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
|
avoids flushing the processor pipeline. The opposite happens if you use the
|
||||||
<code> <span class='ectt-1000'>likely</span>
|
<code> <span class='ectt-1000'>likely</span>
|
||||||
</code> macro.
|
</code> macro.
|
||||||
</p><!-- l. 1564 --><p class='noindent'>
|
</p><!-- l. 1562 --><p class='noindent'>
|
||||||
</p>
|
</p>
|
||||||
<h3 class='sectionHead' id='common-pitfalls'><span class='titlemark'>0.19 </span> <a id='x1-650000.19'></a>Common Pitfalls</h3>
|
<h3 class='sectionHead' id='common-pitfalls'><span class='titlemark'>0.19 </span> <a id='x1-650000.19'></a>Common Pitfalls</h3>
|
||||||
<!-- l. 1567 --><p class='noindent'>
|
<!-- l. 1565 --><p class='noindent'>
|
||||||
</p>
|
</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>
|
<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. 1569 --><p class='noindent'>You can not do that. In a kernel module, you can only use kernel functions which are
|
<!-- l. 1567 --><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>.
|
the functions you can see in <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>/proc/kallsyms</span></span></span>.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</p><!-- l. 1572 --><p class='noindent'>
|
</p><!-- l. 1570 --><p class='noindent'>
|
||||||
</p>
|
</p>
|
||||||
<h4 class='subsectionHead' id='disabling-interrupts'><span class='titlemark'>0.19.2 </span> <a id='x1-670000.19.2'></a>Disabling interrupts</h4>
|
<h4 class='subsectionHead' id='disabling-interrupts'><span class='titlemark'>0.19.2 </span> <a id='x1-670000.19.2'></a>Disabling interrupts</h4>
|
||||||
<!-- l. 1574 --><p class='noindent'>You might need to do this for a short time and that is OK, but if you do not enable
|
<!-- l. 1572 --><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
|
them afterwards, your system will be stuck and you will have to power it
|
||||||
off.
|
off.
|
||||||
</p><!-- l. 1576 --><p class='noindent'>
|
</p><!-- l. 1574 --><p class='noindent'>
|
||||||
</p>
|
</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>
|
<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. 1578 --><p class='noindent'>For people seriously interested in kernel programming, I recommend <a href='https://kernelnewbies.org'>kernelnewbies.org</a>
|
<!-- l. 1576 --><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
|
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,
|
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
|
as Linus Torvalds said, the best way to learn the kernel is to read the source code
|
||||||
yourself.
|
yourself.
|
||||||
</p><!-- l. 1581 --><p class='indent'> If you are interested in more examples of short kernel modules then searching on
|
</p><!-- l. 1579 --><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
|
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
|
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
|
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
|
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
|
how to defend systems and learning about existing security mechanisms within the
|
||||||
kernel.
|
kernel.
|
||||||
</p><!-- l. 1584 --><p class='indent'> I hope I have helped you in your quest to become a better programmer, or at
|
</p><!-- l. 1582 --><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
|
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.
|
hope you publish them under the GPL, so I can use them too.
|
||||||
</p><!-- l. 1587 --><p class='indent'> If you would like to contribute to this guide or notice anything glaringly wrong,
|
</p><!-- l. 1585 --><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>.
|
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. 1589 --><p class='indent'> Happy hacking!
|
</p><!-- l. 1587 --><p class='indent'> Happy hacking!
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user