Linux下编写自己的第一个内核模块
<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;"> 这是我编写好的测试程序,大家可以下载使用。文件:<a class="btn btn-success" href="https://pan.baidu.com/share/init?surl=eQhaflg" target="_blank">点此下载</a> 密码:<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('/uploads/AilsonJack/2018.08.18/1534602662298434.png')"/></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 <linux/init.h>
#include <linux/module.h>
//模块加载函数
static int hello_init(void)
{
printk(KERN_EMERG "Hello World!\n");
return 0;
}
//模块卸载函数
static void hello_exit(void)
{
printk(KERN_EMERG "GoodBye World!\n");
}
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('/uploads/AilsonJack/2018.08.18/1534602662868084.png')"/></p><p style="text-align:center"><img src="/uploads/AilsonJack/2018.08.18/1534602662886511.png" onclick="preview_image('/uploads/AilsonJack/2018.08.18/1534602662886511.png')"/></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 ($(KERNELRELEASE),)
obj-m:=hello.o #在实际中这个需要改变
else
PWD:=$(shell pwd)
#KDIR:=/lib/modules/2.6.32.65/build #在实际中,这个也需要改变
KDIR:=/lib/modules/$(shell uname -r)/build #也可以写成这种形式
all:
make -C $(KDIR) M=$(PWD) modules
clean:
rm -f *.ko *.o *.mod.o *.mod.c *.symvers *.order
endif</pre><p style="text-align:center"><img src="/uploads/AilsonJack/2018.08.18/1534602663555445.png" onclick="preview_image('/uploads/AilsonJack/2018.08.18/1534602663555445.png')"/></p><p style="text-align:center"><img src="/uploads/AilsonJack/2018.08.18/1534602662527313.png" onclick="preview_image('/uploads/AilsonJack/2018.08.18/1534602662527313.png')"/></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 如:<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 如:<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 如:<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('/uploads/AilsonJack/2018.08.18/1534602666406153.png')"/></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('/uploads/AilsonJack/2018.08.18/1534602669512118.png')"/></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('/uploads/AilsonJack/2018.08.18/1534602668401815.png')"/></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('/uploads/AilsonJack/2018.08.18/1534602669522187.png')"/></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.许可证声明: <span style="color: rgb(0, 112, 192);">MODULE_LICENSE(“GPL”);//常用的如:GPL</span></p><p style="text-indent: 2em;">b.模块作者: <span style="color: rgb(0, 112, 192);">MODULE_AUTHOR(“Ailson Jack”);</span></p><p style="text-indent: 2em;">c.模块描述: <span style="color: rgb(0, 112, 192);">MODULE_DESCRIPTION(“Hello World Module”);</span></p><p style="text-indent: 2em;">d.模块版本: <span style="color: rgb(0, 112, 192);">MODULE_VERSION(“V1.0”);</span></p><p style="text-indent: 2em;">e.模块别名: <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);"> S_IRUGO</span>:任何用户都对/sys/module中出现的该参数具有读权限</p><p style="text-indent: 2em;"><span style="color: rgb(0, 112, 192);"> 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>
你可能也喜欢:
暂无评论,要不要来个沙发
发表评论
JLink V9掉固件修复(灯不亮) 3Zephyr笔记2 - 在STM32F429上运行HelloWorld 2计算NandFlash要传入的行地址和列地址 1Linux MMC子系统 - 6.eMMC 5.1工作模式-设备识别模式 0Linux MMC子系统 - 5.eMMC 5.1工作模式-引导模式 0Linux MMC子系统 - 4.eMMC 5.1常用命令说明(2) 0
标签云
Linux嵌入式实用技巧ARM内核学习问题集合CC++编程语言阅读笔记汇编Linux内核完全注释Windows驱动开发计算机基础ARM11ARMv7-ASTM32IDESublimeLinux内核学习eMMCMMC子系统Ubuntu操作系统OfficeVMWareAPUEgccRTOS中断漫游世界随笔感悟开发工具软件应用编程VsCodearmccarmclang编译器ZephyrSPIJLink网卡驱动安装各种芯片库函数NFSμCOS内核sambaFlashUnix命令与脚本输入法Linux内核设计与实现gitRIFFWAVJATGFTPar8161安装centos有线上网μCGUI字库工程建立右键菜单网络文件系统Firefox百度NTFS文件系统CodeBlocksCentOS数据结构算法PhotoShop51KeilQTUltraEditscanfglibc宏定义UIDGID优先级娱乐天地SourceInsight磁盘扇区总线I2CPDFBComparePythonI2SFPUMakefileSWDCPUARP软件推荐FileZilla