1
0
mirror of https://github.com/bashrc/LKMPG.git synced 2018-06-11 03:06:54 +02:00

Make the license example less of a sprawl

This commit is contained in:
Bob Mottram
2016-03-09 12:25:15 +00:00
parent 087af6386d
commit 475abdff82
2 changed files with 48 additions and 148 deletions

View File

@@ -3,7 +3,7 @@
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<!-- 2016-03-08 Tue 15:42 -->
<!-- 2016-03-09 Wed 12:24 -->
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>The Linux Kernel Module Programming Guide</title>
@@ -283,7 +283,7 @@ for the JavaScript code in this tag.
</li>
<li><a href="#orgheadline57">Using /proc For Input</a>
<ul>
<li><a href="#orgheadline56"><span class="todo TODO">TODO</span> : Write a chapter about sysfs</a></li>
<li><a href="#orgheadline56">sysfs: Interacting with your module</a></li>
</ul>
</li>
<li><a href="#orgheadline58">Talking To Device Files</a>
@@ -377,7 +377,7 @@ If you publish or distribute this book commercially, donations, royalties, and/o
</p>
<p>
The Linux Kernel Module Programming Guide was originally written for the 2.2 kernels by Ori Pomerantz. Eventually, Ori no longer had time to maintain the document. After all, the Linux kernel is a fast moving target. Peter Jay Salzman took over maintenance and updated it for the 2.4 kernels. Eventually, Peter no longer had time to follow developments with the 2.6 kernel, so Michael Burian became a co-maintainer to update the document for the 2.6 kernels. Bob Mottram updated the examples for 3.16 kernels.
The Linux Kernel Module Programming Guide was originally written for the 2.2 kernels by Ori Pomerantz. Eventually, Ori no longer had time to maintain the document. After all, the Linux kernel is a fast moving target. Peter Jay Salzman took over maintenance and updated it for the 2.4 kernels. Eventually, Peter no longer had time to follow developments with the 2.6 kernel, so Michael Burian became a co-maintainer to update the document for the 2.6 kernels. Bob Mottram updated the examples for 3.8 and 3.16 kernels.
</p>
<p>
@@ -986,56 +986,11 @@ Module xxxxxx loaded, with warnings
</div>
<p>
There is a mechanism to identify code licensed under the GPL (and friends) so that people can be warned about closed source proprietary stuff, which is likely to be a security problem. This is accomplished by the <b>MODULE_LICENSE()</b> macro which is demonstrated in the next piece of code. By setting the license to GPL, you can keep the warning from being printed. This license mechanism is defined and documented in <b>linux/module.h</b>:
</p>
<div class="org-src-container">
<pre class="src src-c"><span class="org-comment-delimiter">/*</span>
<span class="org-comment"> * The following license idents are currently accepted as indicating free</span>
<span class="org-comment"> * software modules</span>
<span class="org-comment"> *</span>
<span class="org-comment"> * "GPL" [GNU Public License v2 or later]</span>
<span class="org-comment"> * "GPL v2" [GNU Public License v2]</span>
<span class="org-comment"> * "GPL and additional rights" [GNU Public License v2 rights and more]</span>
<span class="org-comment"> * "Dual BSD/GPL" [GNU Public License v2</span>
<span class="org-comment"> * or BSD license choice]</span>
<span class="org-comment"> * "Dual MIT/GPL" [GNU Public License v2</span>
<span class="org-comment"> * or MIT license choice]</span>
<span class="org-comment"> * "Dual MPL/GPL" [GNU Public License v2</span>
<span class="org-comment"> * or Mozilla license choice]</span>
<span class="org-comment"> *</span>
<span class="org-comment"> * The following other idents are available</span>
<span class="org-comment"> *</span>
<span class="org-comment"> * "Proprietary" [Non free products]</span>
<span class="org-comment"> *</span>
<span class="org-comment"> * There are dual licensed components, but when running with Linux it is the</span>
<span class="org-comment"> * GPL that is relevant so this is a non issue. Similarly LGPL linked with GPL</span>
<span class="org-comment"> * is a GPL combined work.</span>
<span class="org-comment"> *</span>
<span class="org-comment"> * This exists for several reasons</span>
<span class="org-comment"> * 1. So modinfo can show license info for users wanting to vet their setup</span>
<span class="org-comment"> * is free</span>
<span class="org-comment"> * 2. So the community can ignore bug reports including proprietary modules</span>
<span class="org-comment"> * 3. So vendors can do likewise based on their own policies</span>
<span class="org-comment"> </span><span class="org-comment-delimiter">*/</span>
</pre>
</div>
<p>
Similarly, <b>MODULE_DESCRIPTION()</b> is used to describe what the module does, <b>MODULE_AUTHOR()</b> declares the module's author, and <b>MODULE_SUPPORTED_DEVICE()</b> declares what types of devices the module supports.
You can use a few macros to indicate the license for your module. Some examples are <i>"GPL"</i>, <i>"GPL v2"</i>, <i>"GPL and additional rights"</i>, <i>"Dual BSD/GPL"</i>, <i>"Dual MIT/GPL"</i>, <i>"Dual MPL/GPL"</i> and <i>"Proprietary"</i>. They're defined within <b>linux/module.h</b>.
</p>
<p>
These macros are all defined in <b>linux/module.h</b> and aren't used by the kernel itself. They're simply for documentation and can be viewed by a tool like objdump. As an exercise to the reader, try and search fo these macros in <b>linux/drivers</b> to see how module authors use these macros to document their modules.
</p>
<p>
I'd recommend to use something like <b>grep -inr MODULE_AUTHOR</b> in <b><i>usr/src/linux-3.16.x</i></b>. People unfamiliar with command line tools will probably like some web base solution, search for sites that offer kernel trees that got indexed with LXR. (or setup it up on your local machine).
</p>
<p>
Users of traditional Unix editors, like emacs or vi will also find tag files useful. They can be generated by make tags or make TAGS in <b><i>usr/src/linux-3.16.x</i></b>. Once you've got such a tagfile in your kernel tree you can put the cursor on some function call and use some key combination to directly jump to the definition function.
To reference what license you're using a macro is available called <b>MODULE_LICENSE</b>. This and a few other macros describing the module are illustrated in the below example.
</p>
</div>
@@ -1050,8 +1005,11 @@ Users of traditional Unix editors, like emacs or vi will also find tag files use
<span class="org-preprocessor">#include</span> <span class="org-string">&lt;linux/module.h&gt;</span> <span class="org-comment-delimiter">/* </span><span class="org-comment">Needed by all modules </span><span class="org-comment-delimiter">*/</span>
<span class="org-preprocessor">#include</span> <span class="org-string">&lt;linux/kernel.h&gt;</span> <span class="org-comment-delimiter">/* </span><span class="org-comment">Needed for KERN_INFO </span><span class="org-comment-delimiter">*/</span>
<span class="org-preprocessor">#include</span> <span class="org-string">&lt;linux/init.h&gt;</span> <span class="org-comment-delimiter">/* </span><span class="org-comment">Needed for the macros </span><span class="org-comment-delimiter">*/</span>
<span class="org-preprocessor">#define</span> <span class="org-variable-name">DRIVER_AUTHOR</span> <span class="org-string">"Peter Jay Salzman <a href="mailto:p%40dirac.org">&lt;p@dirac.org&gt;</a>"</span>
<span class="org-preprocessor">#define</span> <span class="org-variable-name">DRIVER_DESC</span> <span class="org-string">"A sample driver"</span>
MODULE_LICENSE(<span class="org-string">"GPL"</span>);
MODULE_AUTHOR(<span class="org-string">"Bob Mottram"</span>);
MODULE_DESCRIPTION(<span class="org-string">"A sample driver"</span>);
MODULE_SUPPORTED_DEVICE(<span class="org-string">"testdevice"</span>);
<span class="org-keyword">static</span> <span class="org-type">int</span> <span class="org-function-name">__init</span> init_hello_4(<span class="org-type">void</span>)
{
@@ -1066,28 +1024,6 @@ Users of traditional Unix editors, like emacs or vi will also find tag files use
module_init(init_hello_4);
module_exit(cleanup_hello_4);
<span class="org-comment-delimiter">/*</span>
<span class="org-comment"> * You can use strings, like this:</span>
<span class="org-comment"> </span><span class="org-comment-delimiter">*/</span>
<span class="org-comment-delimiter">/*</span>
<span class="org-comment"> * Get rid of taint message by declaring code as GPL.</span>
<span class="org-comment"> </span><span class="org-comment-delimiter">*/</span>
MODULE_LICENSE(<span class="org-string">"GPL"</span>);
<span class="org-comment-delimiter">/*</span>
<span class="org-comment"> * Or with defines, like this:</span>
<span class="org-comment"> </span><span class="org-comment-delimiter">*/</span>
MODULE_AUTHOR(DRIVER_AUTHOR); <span class="org-comment-delimiter">/* </span><span class="org-comment">Who wrote this module? </span><span class="org-comment-delimiter">*/</span>
MODULE_DESCRIPTION(DRIVER_DESC); <span class="org-comment-delimiter">/* </span><span class="org-comment">What does this module do </span><span class="org-comment-delimiter">*/</span>
<span class="org-comment-delimiter">/*</span>
<span class="org-comment"> * This module uses /dev/testdevice. The MODULE_SUPPORTED_DEVICE macro might</span>
<span class="org-comment"> * be used in the future to help automatic configuration of modules, but is</span>
<span class="org-comment"> * currently unused other than for documentation purposes.</span>
<span class="org-comment"> </span><span class="org-comment-delimiter">*/</span>
MODULE_SUPPORTED_DEVICE(<span class="org-string">"testdevice"</span>);
</pre>
</div>
</div>
@@ -2075,8 +2011,7 @@ HelloWorld!
<span class="org-type">size_t</span> <span class="org-variable-name">buffer_length</span>, <span class="org-type">loff_t</span> * <span class="org-variable-name">offset</span>)
{
<span class="org-type">int</span> <span class="org-variable-name">ret</span>=0;
<span class="org-keyword">if</span>(strlen(buffer) ==0)
{
<span class="org-keyword">if</span>(strlen(buffer) ==0) {
printk(KERN_INFO <span class="org-string">"procfile read %s\n"</span>,filePointer-&gt;f_path.dentry-&gt;d_name.name);
ret=copy_to_user(buffer,<span class="org-string">"HelloWorld!\n"</span>,<span class="org-keyword">sizeof</span>(<span class="org-string">"HelloWorld!\n"</span>));
ret=<span class="org-keyword">sizeof</span>(<span class="org-string">"HelloWorld!\n"</span>);
@@ -2093,8 +2028,7 @@ HelloWorld!
<span class="org-type">int</span> <span class="org-function-name">init_module</span>()
{
Our_Proc_File = proc_create(procfs_name,0644,<span class="org-constant">NULL</span>,&amp;proc_file_fops);
<span class="org-keyword">if</span>(<span class="org-constant">NULL</span>==Our_Proc_File)
{
<span class="org-keyword">if</span>(<span class="org-constant">NULL</span>==Our_Proc_File) {
proc_remove(Our_Proc_File);
printk(KERN_ALERT <span class="org-string">"Error:Could not initialize /proc/%s\n"</span>,procfs_name);
<span class="org-keyword">return</span> -ENOMEM;
@@ -2174,8 +2108,7 @@ The only memory segment accessible to a process is its own, so when writing regu
<span class="org-type">size_t</span> <span class="org-variable-name">buffer_length</span>, <span class="org-type">loff_t</span> * <span class="org-variable-name">offset</span>)
{
<span class="org-type">int</span> <span class="org-variable-name">ret</span>=0;
<span class="org-keyword">if</span>(strlen(buffer) ==0)
{
<span class="org-keyword">if</span>(strlen(buffer) ==0) {
printk(KERN_INFO <span class="org-string">"procfile read %s\n"</span>,filePointer-&gt;f_path.dentry-&gt;d_name.name);
ret=copy_to_user(buffer,<span class="org-string">"HelloWorld!\n"</span>,<span class="org-keyword">sizeof</span>(<span class="org-string">"HelloWorld!\n"</span>));
ret=<span class="org-keyword">sizeof</span>(<span class="org-string">"HelloWorld!\n"</span>);
@@ -2215,8 +2148,7 @@ The only memory segment accessible to a process is its own, so when writing regu
<span class="org-type">int</span> <span class="org-function-name">init_module</span>()
{
Our_Proc_File = proc_create(PROCFS_NAME,0644,<span class="org-constant">NULL</span>,&amp;proc_file_fops);
<span class="org-keyword">if</span>(<span class="org-constant">NULL</span>==Our_Proc_File)
{
<span class="org-keyword">if</span>(<span class="org-constant">NULL</span>==Our_Proc_File) {
proc_remove(Our_Proc_File);
printk(KERN_ALERT <span class="org-string">"Error:Could not initialize /proc/%s\n"</span>,PROCFS_NAME);
<span class="org-keyword">return</span> -ENOMEM;
@@ -2245,7 +2177,7 @@ The only memory segment accessible to a process is its own, so when writing regu
<h3 id="orgheadline51">Manage /proc file with standard filesystem</h3>
<div class="outline-text-3" id="text-orgheadline51">
<p>
We have seen how to read and write a /proc file with the /proc interface. But it's also possible to manage /proc file with inodes. The main interest is to use advanced function, like permissions.
We have seen how to read and write a /proc file with the /proc interface. But it's also possible to manage /proc file with inodes. The main concern is to use advanced functions, like permissions.
</p>
<p>
@@ -2676,11 +2608,35 @@ You can also read the code of fs/seq_file.c in the linux kernel.
<h2 id="orgheadline57">Using /proc For Input</h2>
<div class="outline-text-2" id="text-orgheadline57">
</div><div id="outline-container-orgheadline56" class="outline-3">
<h3 id="orgheadline56"><span class="todo TODO">TODO</span> : Write a chapter about sysfs</h3>
<h3 id="orgheadline56">sysfs: Interacting with your module</h3>
<div class="outline-text-3" id="text-orgheadline56">
<p>
This is just a placeholder for now. Finally I'd like to see a (yet to be written) chapter about sysfs instead here. If you are familiar with sysfs and would like to take part in writing this chapter, feel free to contact us (the LKMPG maintainers) for further details.
sysfs allows you to interact with the running kernel by reading or setting variables inside of modules. This can be useful for debugging purposes, or just as an interface for userland applications.
</p>
<p>
An example of a hello world module which includes a variable accessible via sysfs is given below.
</p>
<div class="org-src-container">
<pre class="src src-c">TODO
</pre>
</div>
<p>
Then to test it:
</p>
<div class="org-src-container">
<pre class="src src-sh">make
sudo insmod hello-sysfs.ko
sudo lsmod | grep hello_sysfs
sudo rmmod hello_sysfs
</pre>
</div>
</div>
</div>
</div>

View File

@@ -401,46 +401,9 @@ Warning: loading xxxxxx.ko will taint the kernel: no license
Module xxxxxx loaded, with warnings
#+END_SRC
There is a mechanism to identify code licensed under the GPL (and friends) so that people can be warned about closed source proprietary stuff, which is likely to be a security problem. This is accomplished by the *MODULE_LICENSE()* macro which is demonstrated in the next piece of code. By setting the license to GPL, you can keep the warning from being printed. This license mechanism is defined and documented in *linux/module.h*:
You can use a few macros to indicate the license for your module. Some examples are /"GPL"/, /"GPL v2"/, /"GPL and additional rights"/, /"Dual BSD/GPL"/, /"Dual MIT/GPL"/, /"Dual MPL/GPL"/ and /"Proprietary"/. They're defined within *linux/module.h*.
#+BEGIN_SRC c
/*
* The following license idents are currently accepted as indicating free
* software modules
*
* "GPL" [GNU Public License v2 or later]
* "GPL v2" [GNU Public License v2]
* "GPL and additional rights" [GNU Public License v2 rights and more]
* "Dual BSD/GPL" [GNU Public License v2
* or BSD license choice]
* "Dual MIT/GPL" [GNU Public License v2
* or MIT license choice]
* "Dual MPL/GPL" [GNU Public License v2
* or Mozilla license choice]
*
* The following other idents are available
*
* "Proprietary" [Non free products]
*
* There are dual licensed components, but when running with Linux it is the
* GPL that is relevant so this is a non issue. Similarly LGPL linked with GPL
* is a GPL combined work.
*
* This exists for several reasons
* 1. So modinfo can show license info for users wanting to vet their setup
* is free
* 2. So the community can ignore bug reports including proprietary modules
* 3. So vendors can do likewise based on their own policies
*/
#+END_SRC
Similarly, *MODULE_DESCRIPTION()* is used to describe what the module does, *MODULE_AUTHOR()* declares the module's author, and *MODULE_SUPPORTED_DEVICE()* declares what types of devices the module supports.
These macros are all defined in *linux/module.h* and aren't used by the kernel itself. They're simply for documentation and can be viewed by a tool like objdump. As an exercise to the reader, try and search fo these macros in *linux/drivers* to see how module authors use these macros to document their modules.
I'd recommend to use something like *grep -inr MODULE_AUTHOR* in */usr/src/linux-3.16.x/*. People unfamiliar with command line tools will probably like some web base solution, search for sites that offer kernel trees that got indexed with LXR. (or setup it up on your local machine).
Users of traditional Unix editors, like emacs or vi will also find tag files useful. They can be generated by make tags or make TAGS in */usr/src/linux-3.16.x/*. Once you've got such a tagfile in your kernel tree you can put the cursor on some function call and use some key combination to directly jump to the definition function.
To reference what license you're using a macro is available called *MODULE_LICENSE*. This and a few other macros describing the module are illustrated in the below example.
*** Example: hello-4.c
#+BEGIN_SRC c
@@ -450,8 +413,11 @@ Users of traditional Unix editors, like emacs or vi will also find tag files use
#include <linux/module.h> /* Needed by all modules */
#include <linux/kernel.h> /* Needed for KERN_INFO */
#include <linux/init.h> /* Needed for the macros */
#define DRIVER_AUTHOR "Peter Jay Salzman <p@dirac.org>"
#define DRIVER_DESC "A sample driver"
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Bob Mottram");
MODULE_DESCRIPTION("A sample driver");
MODULE_SUPPORTED_DEVICE("testdevice");
static int __init init_hello_4(void)
{
@@ -466,28 +432,6 @@ static void __exit cleanup_hello_4(void)
module_init(init_hello_4);
module_exit(cleanup_hello_4);
/*
* You can use strings, like this:
*/
/*
* Get rid of taint message by declaring code as GPL.
*/
MODULE_LICENSE("GPL");
/*
* Or with defines, like this:
*/
MODULE_AUTHOR(DRIVER_AUTHOR); /* Who wrote this module? */
MODULE_DESCRIPTION(DRIVER_DESC); /* What does this module do */
/*
* This module uses /dev/testdevice. The MODULE_SUPPORTED_DEVICE macro might
* be used in the future to help automatic configuration of modules, but is
* currently unused other than for documentation purposes.
*/
MODULE_SUPPORTED_DEVICE("testdevice");
#+END_SRC
** Passing Command Line Arguments to a Module