简单实例讲解linux的module模块编译步骤

来源:互联网 发布:curl 发送json数据 编辑:程序博客网 时间:2024/05/01 03:33

简单实例讲解linux的module模块编译步骤 (2014-10-24 10:19:17)
转载:http://blog.sina.com.cn/lvxuecheng

标签: 

module

 

linux

 分类: Linux/Unix

本文将直接了当的带你进入linux的模块编译。当然在介绍的过程当中,我也会添加一些必要的注释,以便初学者能够看懂。之所以要写这篇文章,主要是因为从书本上学的话,可能要花更长的时间才能学会整个过程,因为看书的话是一个学习过程,而我这篇文章更像是一个培训。所以实践性和总结性更强。通过本文你将会学到编译一个模块和模块makefile的基本知识。以及加载(卸载)模块,查看系统消息的一些知识;

声明:本文为初学者所写,如果你已经是一个linux模块编译高手,还请指正我文章中的错误和不足,谢谢

第一步:准备源代码

首先我们还是要来编写一个符合linux格式的模块文件,这样我们才能开始我们的模块编译。假设我们有一个源文件mymod.c。它的源码如下:

mymod.c

  1. #include       
  2. #include           
  3. #include   
  4. MODULE_AUTHOR("Yu Qiang");  
  5. MODULE_LICENSE("GPL");   
  6. static int nbr 10;  
  7. module_param(nbr, intS_IRUGO);  
  8.   
  9. static int __init yuer_init(void 
  10.  
  11.     int i;  
  12.     for(i=0; i
  13.      
  14.         printk(KERN_ALERT "Hello, How are you. %d\n"i);  
  15.      
  16.     return 0;  
  17.  
  18.   
  19. static void __exit yuer_exit(void 
  20.  
  21.     printk(KERN_ALERT"I come from yuer's modulehave been unlad.\n");  
  22.  
  23. module_init(yuer_init);  
  24. module_exit(yuer_exit);  



我们的源文件就准备的差不多了,这就是一个linux下的模块的基本结构。第9行是导出我们的符号变量nbr。这样在你加载这个模块的时候可以动态修改这个变量的值。稍后将演示。yuer_init()函数将在模块加载的时候运行,通过输出的结果可以看到我们的模块是否加载成功。


第二步:编写Makefile文件
    
首先还是来看看我们Makefile的源文件,然后我们再来解释;

Makefile
obj-m := modules.o                   #要生成的模块名     
modules-objs:= mymod.o        #生成这个模块名所需要的目标文件

KDIR := /lib/modules/`uname -r`/build
PWD := $(shell pwd)

default:
make -C $(KDIR) M=$(PWD) modules

clean:
rm -rf *.o .* .cmd *.ko *.mod.c .tmp_versions


现在我来说明一下这个Makefile。请记住是大写的Makefile而不是小写的makefile;
obj-m :这个变量是指定你要声称哪些模块模块的格式为 obj-m := <模块名>.o
modules-objs :这个变量是说明声称模块modules需要的目标文件 格式要求   <模块名>-objs := <目标文件>
       切记:模块的名字不能取与目标文件相同的名字。如在这里模块名不能取成 mymod;
KDIR   :这是我们正在运行的操作系统内核编译目录。也就是编译模块需要的环境
M=     :指定我们源文件的位置
PWD   :这是当前工作路径$(shell   )是make的一个内置函数。用来执行shell命令。


第三步:编译模块

现在我们已经准备好了我们所需要的源文件和相应的Makefile。我们现在就可以编译了。在终端进入源文件目录输入make
运行结果:
  1. make[1]: Entering directory `/usr/src/linux-headers-2.6.24-24-generic'  
  2. CC [M] /home/yuqiang/桌面/mymodule/mymodules.o  
  3. LD [M] /home/yuqiang/桌面/mymodule/modules.o  
  4. Building modules, stage 2.  
  5. MODPOST 1 modules  
  6. CC      /home/yuqiang/桌面/mymodule/modules.mod.o  
  7. LD [M] /home/yuqiang/桌面/mymodule/modules.ko  
  8. make[1]: Leaving directory `/usr/src/linux-headers-2.6.24-24-generic'  




第四步:加载/卸载我们的模块

从上面的编译中我可以看到。已经有一个modules.ko生成了。这就是我们的模块了。现在我们就可以来加载了。
首先在终端输入:sudo insmod modules.ko
现在我们来看看我们的模块加载成功没有呢?
在终端输入:dmesg | tail -12   这是查看内核输出信息的意思。tail -12 显示最后12条;
显示结果如下:
  1. [17945.024417] sd 9:0:0:0: Attached scsi generic sg2 type  
  2. [18046.790019] usb 5-8: USB disconnect, address  
  3. [19934.224812] Hello, How are you.  
  4. [19934.224817] Hello, How are you.  
  5. [19934.224818] Hello, How are you.  
  6. [19934.224820] Hello, How are you.  
  7. [19934.224821] Hello, How are you.  
  8. [19934.224822] Hello, How are you.  
  9. [19934.224824] Hello, How are you.  
  10. [19934.224825] Hello, How are you.  
  11. [19934.224826] Hello, How are you.  
  12. [19934.224828] Hello, How are you.  



看到了吧。我们的模块的初始化函数yuer_init();已经成功运行了。说明我们的模块已经加载成功;
现在我们再来卸载模块试试看。
在终端输入:sudo rmmod modules
在终端输入:dmesg | tail -3
  1. [19934.224826] Hello, How are you.  
  2. [19934.224828] Hello, How are you.  
  3. [20412.046932] come from yuer's modulehave been unlad.  



可以从打印的信息中看到,我们的模块的退出函数已经被执行了。说明我们的模块已经被成功的卸载了。到目前位置我们就已经算是对模块的编译到编译运行算是有了一个整体上的认识了。对于以后深入的学习还是应该有点帮助的。下面我们将在看看于模块相关的一些简单的操作。


第五步:加载模块时传递参数
在终端输入:sudo insmod module_name.ko nbr=4
在终端输入:dmesg | tail -6
显示结果如下:
  1. [20800.655694] Hello, How are you.  
  2. [21318.675593] come from onefile modulehave been unlad.  
  3. [21334.425373] Hello, How are you.  
  4. [21334.425378] Hello, How are you.  
  5. [21334.425380] Hello, How are you.  
  6. [21334.425381] Hello, How are you.  



这样我们就可以看到在模块加载的时候动态设置了我们的一个变量。初始化函数中的循环只执行了4次。
可能你会问我怎么知道一个模块可以设置那些变量呢。当然,你可以先不设变量加载一次。然后可以在终端输入ls /sys/module//parameters/来查看。在这里我们是这样输入的
在终端输入:ls /sys/moedle/modules/parameters/
显示结果:
nbr

如果我们的模块加载成功了。最后我们还可以通过modinfo来查看我们的模块信息。如下
在终端输入:sudo modinfo modules.ko
    显示结果:
  1. filename:       modules.ko  
  2. license:        GPL  
  3. author:         Yu Qiang  
  4. srcversion:     20E9C3C4E02D130E6E92533  
  5. depends:          
  6. vermagic:       2.6.24-24-generic SMP mod_unload 586   
  7. parm:           nbr:int  




本文总结:
    本文的相关知识都好像有一点浅尝辙止的感觉。因为本篇文章主要是通过一条线式方式来讲解了模块编写的相关过程,其实在这个过程中还有很多可以发散的地方。例如:
在写到MODULE_AUTHOR("Yu Qiang")的时候,你应该想到还有
     MODULE_DESCRIPTION(模块用途的简单描述);
    MODULE_VERSION(模块的版本字符串);
    MODULE_ALIAS(模块的别名);
    ...

在写到module_param(nbr, int, S_IRUGO);的时候,你应该想到还有
     EXPORT_SYMBOL(name); 可以导出模块的函数,这也是模块编写的最终目的
...

在用到insmod 和 modinfo的时候。你应该想到还有
    depmod     分析可加载模块的依赖性,并生成modules.dep文件和映射文件
    modprobe   Linux内核添加删除模块
...

阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 lr变成英文版怎么办 r和l不分怎么办 小孩发音nl不分怎么办 l和n不分怎么办 好朋友喜欢上我怎么办 感觉在一起好累怎么办 善心汇限制出行怎么办 很孤独的时候怎么办 啪啪被孩子撞见怎么办 老是和老公吵架怎么办 跟老公吵架后怎么办 和老公吵架后怎么办 毛笔尖钝了怎么办 晚上睡不着白天睡不醒怎么办 羊绒衫穿着扎人怎么办 羊绒衫洗后缩水怎么办 qq火花掉了怎么办 交易猫恶意仲裁怎么办 qq 密码忘记了怎么办 至尊宝非要解除怎么办 手机qq密保忘了怎么办 qq密保不记得了怎么办 qq手机验证不了怎么办 qq空间违规了怎么办 qq游戏不能安装怎么办 电脑qq无法安装怎么办 手机内存用完了怎么办 苹果4空间不足怎么办 小孩子舌头烫了怎么办 小孩喝水烫舌头怎么办 烫舌头怎么办小窍门 手机游戏延迟高怎么办 fps游戏延迟高怎么办 电脑删不了软件怎么办 顺丰宠物托运怎么办 忘了打印准考证怎么办 仓鼠突然瘦了怎么办 手机充电超级慢怎么办 法斗肚子有个包怎么办 狗狗一直气喘怎么办 被绿了一蹶不振怎么办