Linux下编写自己的第一个内核模块
 2015.04.20    |      内核学习    |     AilsonJack    |     暂无评论    |     1213 views
广告位C招租:1
By: Ailson Jack
Date: 2015-04-20
个人博客: http://www.only2fire.com/
<p style="text-indent: 2em;">今天给大家讲讲Linux内核模块的编写吧,这里涉及的模块很简单,旨在给大家提供一个模块编写的范例,本文的<span style="color: rgb(255, 0, 0);">Makefile</span>文件大家可以参考着用于自己的模块,我觉得这个Makefile文件还是很不错的<img src="/UEditor/dialogs/emotion/images/face/i_f03.gif"/>。</p><p style="text-indent: 2em;">在讲述之前先说说Linux内核模块的特点吧。Linux内核模块具有如下特点:</p><p style="text-indent: 2em;"><span style="color: rgb(255, 0, 0);">a.</span>模块本身并不被编译进内核文件(zImage或者bzImage)</p><p style="text-indent: 2em;"><span style="color: rgb(255, 0, 0);">b.</span>可以根据需求,在内核运行期间,动态的安装或者卸载模块</p><p style="text-indent: 2em;">本文使用的是Fedora操作系统(运行在虚拟机中),Linux内核为<span style="color: rgb(255, 0, 0);">linux-2.6.32.65</span>,是自己编译的,至于怎么在虚拟机中安装Feodra以及如何自己编译Linux内核,大家可以参考我写的文章:<a href="http://www.only2fire.com/archives/14.html" target="_blank"><strong><span style="color: rgb(255, 0, 0);">Linux内核配置、编译、安装</span></strong></a>,对于自己学习还是建议自己编译一个内核来使用。</p><p style="text-indent: 0em;">&nbsp;&nbsp;这是我编写好的测试程序,大家可以下载使用。文件:<a class="btn btn-success" href="https://pan.baidu.com/share/init?surl=eQhaflg" target="_blank">点此下载</a>&nbsp; 密码:<span style="color: rgb(255, 0, 0);">ot9t</span>。</p><p class="artical_littlestyle1">1、编写hello.c代码</p><p style="text-indent: 2em;">打开Fedora,打开终端,切换为root用户,这些很简单,就不详细说了,然后在创建一个hello目录,我创建的目录如下:</p><p style="text-align:center"><img src="/uploads/AilsonJack/2018.08.18/1534602662298434.png" onclick="preview_image(&#39;/uploads/AilsonJack/2018.08.18/1534602662298434.png&#39;)"/></p><p style="text-indent: 2em;">然后执行命令:<span style="color: rgb(255, 0, 0);">vi hello.c</span>,在里面输入如下内容:<br/></p><pre class="brush:cpp;toolbar:false PrismJs">#include&nbsp;&lt;linux/init.h&gt; #include&nbsp;&lt;linux/module.h&gt; //模块加载函数 static&nbsp;int&nbsp;hello_init(void) { &nbsp;&nbsp;&nbsp;&nbsp;printk(KERN_EMERG&nbsp;&quot;Hello&nbsp;World!\n&quot;); &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;0; } //模块卸载函数 static&nbsp;void&nbsp;hello_exit(void) { &nbsp;&nbsp;&nbsp;&nbsp;printk(KERN_EMERG&nbsp;&quot;GoodBye&nbsp;World!\n&quot;); } module_init(hello_init); module_exit(hello_exit);</pre><p style="text-align:center"><img src="/uploads/AilsonJack/2018.08.18/1534602662868084.png" onclick="preview_image(&#39;/uploads/AilsonJack/2018.08.18/1534602662868084.png&#39;)"/></p><p style="text-align:center"><img src="/uploads/AilsonJack/2018.08.18/1534602662886511.png" onclick="preview_image(&#39;/uploads/AilsonJack/2018.08.18/1534602662886511.png&#39;)"/></p><p style="text-indent: 2em;">编写好后,保存退出。</p><p class="artical_littlestyle2">2、编写Makefile文件</p><p style="text-indent: 2em;">执行命令:<span style="color: rgb(255, 0, 0);">vi Makefile</span>,在Makefile中输入以下内容:</p><p style="text-indent: 2em;"><span style="color: rgb(255, 0, 0);">注:</span>Makefile中的<span style="color: rgb(255, 0, 0);">M</span>字母是大写的。</p><pre class="brush:bash;toolbar:false PrismJs">ifneq&nbsp;($(KERNELRELEASE),) obj-m:=hello.o&nbsp;#在实际中这个需要改变 else PWD:=$(shell&nbsp;pwd) #KDIR:=/lib/modules/2.6.32.65/build&nbsp;#在实际中,这个也需要改变 KDIR:=/lib/modules/$(shell&nbsp;uname&nbsp;-r)/build&nbsp;#也可以写成这种形式 all: &nbsp;&nbsp;&nbsp;&nbsp;make&nbsp;-C&nbsp;$(KDIR)&nbsp;M=$(PWD)&nbsp;modules clean: &nbsp;&nbsp;&nbsp;&nbsp;rm&nbsp;-f&nbsp;*.ko&nbsp;*.o&nbsp;*.mod.o&nbsp;*.mod.c&nbsp;*.symvers&nbsp;*.order endif</pre><p style="text-align:center"><img src="/uploads/AilsonJack/2018.08.18/1534602663555445.png" onclick="preview_image(&#39;/uploads/AilsonJack/2018.08.18/1534602663555445.png&#39;)"/></p><p style="text-align:center"><img src="/uploads/AilsonJack/2018.08.18/1534602662527313.png" onclick="preview_image(&#39;/uploads/AilsonJack/2018.08.18/1534602662527313.png&#39;)"/></p><p class="artical_littlestyle3">3、安装、卸载模块</p><p style="text-indent: 2em;">在讲解之前先介绍几个命令:</p><p style="text-indent: 2em;"><span style="color: rgb(0, 112, 192);">加载模块</span>:insmod&nbsp;如:<span style="color: rgb(255, 0, 0);">insmod hello.ko</span></p><p style="text-indent: 2em;"><span style="color: rgb(0, 112, 192);">卸载模块</span>:rmmod&nbsp; 如:<span style="color: rgb(255, 0, 0);">rmmod hello</span></p><p style="text-indent: 2em;"><span style="color: rgb(0, 112, 192);">查看模块</span>:lsmod&nbsp; 如:<span style="color: rgb(255, 0, 0);">lsmod</span> (可知道当前已加载的模块)</p><p style="text-indent: 2em;">在终端中执行命令:<span style="color: rgb(255, 0, 0);">make</span>,编译模块生成<span style="color: rgb(255, 0, 0);">ko</span>文件:</p><p style="text-align:center"><img src="/uploads/AilsonJack/2018.08.18/1534602666406153.png" onclick="preview_image(&#39;/uploads/AilsonJack/2018.08.18/1534602666406153.png&#39;)"/></p><p style="text-indent: 2em;">然后执行命令:<span style="color: rgb(255, 0, 0);">insmod hello.ko</span>,加载模块,可以看到控制台打印出了信息:</p><p style="text-align:center"><img src="/uploads/AilsonJack/2018.08.18/1534602669512118.png" onclick="preview_image(&#39;/uploads/AilsonJack/2018.08.18/1534602669512118.png&#39;)"/></p><p style="text-indent: 2em;">接着执行命令:<span style="color: rgb(255, 0, 0);">lsmod</span>,可以看到系统已经加载了<span style="color: rgb(255, 0, 0);">hello</span>模块:</p><p style="text-align:center"><img src="/uploads/AilsonJack/2018.08.18/1534602668401815.png" onclick="preview_image(&#39;/uploads/AilsonJack/2018.08.18/1534602668401815.png&#39;)"/></p><p style="text-indent: 2em;">接着执行命令:<span style="color: rgb(255, 0, 0);">rmmod hello</span>,卸载模块,也可以看到打印出的信息:</p><p style="text-align:center"><img src="/uploads/AilsonJack/2018.08.18/1534602669522187.png" onclick="preview_image(&#39;/uploads/AilsonJack/2018.08.18/1534602669522187.png&#39;)"/></p><p style="text-indent: 2em;">以上内容就完成了一个简单的内核模块的加载、卸载过程。下面介绍些其他相关的知识。<br/></p><p class="artical_littlestyle4">4、模块可选信息</p><p style="text-indent: 2em;">在进行模块源代码编写时可以添加以下信息,让模块更加的易读:</p><p style="text-indent: 2em;">a.许可证声明: &nbsp;&nbsp;&nbsp;<span style="color: rgb(0, 112, 192);">MODULE_LICENSE(“GPL”);//常用的如:GPL</span></p><p style="text-indent: 2em;">b.模块作者:&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: rgb(0, 112, 192);">MODULE_AUTHOR(“Ailson Jack”);</span></p><p style="text-indent: 2em;">c.模块描述:&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: rgb(0, 112, 192);">MODULE_DESCRIPTION(“Hello World Module”);</span></p><p style="text-indent: 2em;">d.模块版本:&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: rgb(0, 112, 192);">MODULE_VERSION(“V1.0”);</span></p><p style="text-indent: 2em;">e.模块别名:&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: rgb(0, 112, 192);">MODULE_ALIAS(“test module”);</span></p><p style="text-indent: 2em;">f.模块参数:通过宏<span style="color: rgb(0, 112, 192);">module_param</span>指定模块参数,模块参数用于在模块加载时,传递参数给模块。<br/></p><p style="text-indent: 2em;"><span style="color: rgb(255, 0, 0);">module_param(name,type,perm):</span></p><p style="text-indent: 2em;"><span style="color: rgb(0, 112, 192);">name</span>:模块参数的名称</p><p style="text-indent: 2em;"><span style="color: rgb(0, 112, 192);">type</span>:模块参数的类型</p><p style="text-indent: 2em;"><span style="color: rgb(0, 112, 192);">perm</span>:模块参数的访问权限</p><p style="text-indent: 2em;"><span style="color: rgb(255, 0, 0);">type</span>的常见值有:<span style="color: rgb(0, 112, 192);">bool</span>(布尔型),<span style="color: rgb(0, 112, 192);">int</span>(整型),<span style="color: rgb(0, 112, 192);">charp</span>(字符串型)</p><p style="text-indent: 2em;"><span style="color: rgb(255, 0, 0);">perm</span>的常见值有:</p><p style="text-indent: 2em;"><span style="color: rgb(0, 112, 192);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; S_IRUGO</span>:任何用户都对/sys/module中出现的该参数具有读权限</p><p style="text-indent: 2em;"><span style="color: rgb(0, 112, 192);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; S_IWUSR</span>:允许root用户修改/sys/module中出现的该参数<br/></p><p style="text-indent: 2em;">例如:</p><p style="text-indent: 2em;"><span style="color: rgb(0, 112, 192);">int m=3;</span></p><p style="text-indent: 2em;"><span style="color: rgb(0, 112, 192);">char *n;</span></p><p style="text-indent: 2em;"><span style="color: rgb(0, 112, 192);">module_param(m,int, S_IRUGO);</span></p><p style="text-indent: 2em;"><span style="color: rgb(0, 112, 192);">module_param(n, charp, S_IRUGO);</span><br/></p><p style="text-indent: 2em;">到这里本文算是讲完了,大家有什么疑问可以在网上搜索或者可以留言。</p>
欢迎关注博主的公众号呀,精彩内容随时掌握:
热情邀请仔细浏览下博客中的广告,万一有对自己有用或感兴趣的呢。◕ᴗ◕。。
如果这篇文章对你有帮助,记得点赞和关注博主就行了^_^,当然了能够赞赏博主,那就非常感谢啦!
注: 转载请注明出处,谢谢!^_^
广告位C招租:2
广告位C招租:3
广告位D招租:1
广告位D招租:2
暂无评论,要不要来个沙发
发表评论

 
广告位E招租
Copyright © 2015~2021  说好一起走   保留所有权利   |  百度统计  蜀ICP备15004292号