注:原博文地址http://blog.sina.com.cn/s/blog_4ba5b45e0102v25h.html

-------------------------------------------------------------------------------------------------------------------------------------------

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

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

第一步:准备module源代码


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

mymod.c

 #include <linux/module.h>         /* 引入与模块相关的宏 */
#include <linux/init.h> /* 引入module_init() module_exit()函数 */
#include <linux/moduleparam.h>/* 引入module_param() */
MODULE_AUTHOR("Yu Qiang");
MODULE_LICENSE("GPL");
static int nbr = ; module_param(nbr, int, S_IRUGO); /* 加载模块时传入参数 */ static int __init yuer_init(void) /* 加载模块时自动执行 */
{
int i;
for(i=; i<nbr; i++)
{
printk(KERN_ALERT "Hello, How are you. %d\n", i);
}
return ;
} static void __exit yuer_exit(void)
{
printk(KERN_ALERT"I come from yuer's module, I have been unlad.\n");
}
module_init(yuer_init);
module_exit(yuer_exit);

我们的源文件就准备的差不多了,这就是一个linux下的模块的基本结构。

第8行,是导出我们的符号变量nbr,这样在你加载这个模块的时候可以动态修改这个变量的值,稍后将演示。

第10行,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,一个目录下可以有多个obj-m模块文件,详见kernel源码
modules-objs :这个变量是说明声称模块modules需要的目标文件,格式要求   <模块名>-objs := <目标文件>
       切记:模块的名字不能取与目标文件相同的名字。如在这里模块名不能取成 mymod;
KDIR   :这是我们正在运行的操作系统内核编译目录,也就是编译模块需要的环境,注意,这儿如果是PC module则路径为PC内核路径,如果ARM板则路径为SDK 内核路径
M=     :指定我们源文件的位置
PWD   :这是当前工作路径$(shell  pwd)是make的一个内置函数。用来执行shell命令。
default:第一个目标为Makefile中默认执行的目标

第三步:编译模块


现在我们已经准备好了我们所需要的源文件和相应的Makefile。我们现在就可以编译了。

在终端进入源文件目录输入make
运行结果:

 make[]: Entering directory `/usr/src/linux-headers-2.6.--generic'
CC [M] /home/yuqiang/桌面/mymodule/mymodules.o
LD [M] /home/yuqiang/桌面/mymodule/modules.o
Building modules, stage .
MODPOST modules
CC /home/yuqiang/桌面/mymodule/modules.mod.o
LD [M] /home/yuqiang/桌面/mymodule/modules.ko
make[]: Leaving directory `/usr/src/linux-headers-2.6.--generic'

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


从上面的编译中我可以看到。已经有一个modules.ko生成了。这就是我们的模块了。现在我们就可以来加载了。
首先在终端输入:sudo insmod modules.ko
现在我们来看看我们的模块加载成功没有呢?
在终端输入:dmesg | tail -12   这是查看内核输出信息的意思。tail -12 显示最后12条;
显示结果如下:

 [17945.024417] sd :::: Attached scsi generic sg2 type
[18046.790019] usb -: USB disconnect, address
[19934.224812] Hello, How are you.
[19934.224817] Hello, How are you.
[19934.224818] Hello, How are you.
[19934.224820] Hello, How are you.
[19934.224821] Hello, How are you.
[19934.224822] Hello, How are you.
[19934.224824] Hello, How are you.
[19934.224825] Hello, How are you.
[19934.224826] Hello, How are you.
[19934.224828] Hello, How are you.

看到了吧。我们的模块的初始化函数yuer_init();已经成功运行了。说明我们的模块已经加载成功;
现在我们再来卸载模块试试看。
在终端输入:sudo rmmod modules
在终端输入:dmesg | tail -3

 
 [19934.224826] Hello, How are you.
[19934.224828] Hello, How are you.
[20412.046932] I come from yuer's module, I have been unlad.

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

第五步:加载模块时传递参数


在终端输入:sudo insmod module_name.ko nbr=4
在终端输入:dmesg | tail -6
显示结果如下:

 [20800.655694] Hello, How are you.
[21318.675593] I come from onefile module, I have been unlad.
[21334.425373] Hello, How are you.
[21334.425378] Hello, How are you.
[21334.425380] Hello, How are you.
[21334.425381] Hello, How are you.

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

 nbr

如果我们的模块加载成功了。最后我们还可以通过modinfo来查看我们的模块信息。如下
在终端输入:sudo modinfo modules.ko
    显示结果:

 filename:       modules.ko
license: GPL
author: Yu Qiang
srcversion: 20E9C3C4E02D130E6E92533
depends:
vermagic: 2.6.--generic SMP mod_unload
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内核添加删除模块
...

如果要成为一名专业的linux模块开发人员,还要走很多的路,就看各位的了,祝大家学习顺利。

我并不是什么linux相关的专家,我只是一个普通的linux相关开发人员(在读),我的目的也很简单,就是想给大家介绍一个方法,希望大家在学习的时候不要走过多的弯路。由于个人能力所限难免存在错误和缺点,所以请不要介意,如有发现请提出,我立即修改。方便大家学习

简单实例讲解linux的module模块编译步骤的更多相关文章

  1. linux 模块编译步骤(原)

    linux 模块编译步骤(原) 博主推荐:<Linux命令模板Licote(原)> 本文将直接了当的带你进入linux的模块编译.当然在介绍的过程当中,我也会添加一些必要的注释,以便初学者 ...

  2. 实例讲解Linux系统中硬链接与软链接的创建

    导读 Linux链接分两种,一种被称为硬链接(Hard Link),另一种被称为符号链接(Symbolic Link).默认情况下,ln命令产生硬链接.硬链接与软链接的区别从根本上要从Inode节点说 ...

  3. Linux内核-模块编译和安装

    我安装Ubuntu的时候是没有安装源码的,在没有安装源码前 /usr/src/ 目录下是只有两个包含内核的头文件的文件夹的: 我的内核版本是: 所以接下来就是先安装内核源码: 执行后,/usr/src ...

  4. 实例讲解Linux下的makefile

    1.程序代码结构如下 makefile/ |-- Makefile |-- haha.c `-- hehe.c 1.1.需要被编译的源代码如下 $ cat haha.c #include " ...

  5. appium跑demo简单实例讲解

    安装appium,设置 demo.pyfrom appium import webdriver #要装webdriver,方法查看http://www.cnblogs.com/sincoolvip/p ...

  6. vue.js路由参数简单实例讲解------简单易懂

    vue中,我们构建单页面应用时候,一定必不可少用到vue-router vue-router 就是我们的路由,这个由vue官方提供的插件 首先在我们项目中安装vue-router路由依赖 第一种,我们 ...

  7. SharePoint开发 - TimerJob简单实例讲解

    博客地址 http://blog.csdn.net/foxdave SharePoint中的TimerJob类似于Windows系统的计划任务,可以实现定时执行指定操作的功能. 本篇所述的实例为在Sh ...

  8. JS中的数学计算<之简单实例讲解>

    1.取余数   % var a=10%3; //a=1 2.取绝对值  Math.abs() var a=Math.abs(-102.1); var b=Math.abs(102.1); //a=10 ...

  9. JEECG 简单实例讲解权限控制

    业务背景:某公司要实现一个日志系统,用来了解员工的工作量饱和情况. 需求: 1.角色分为:员工.经理 两种. 2.员工每天在日志系统中填报工作总结,然后经理进行点评. 3.表单内容包含:姓名.日期.工 ...

随机推荐

  1. [转载]新功能:用微软的Live Writer离线写博文

    原文地址:Writer离线写博文">新功能:用微软的Live Writer离线写博文作者:新浪博客 Writer离线写博文" title="[转载]新功能:用微软的 ...

  2. C语言的位运算

    位运算加速技巧1. 如果乘上一个2的倍数数值,可以改用左移运算(Left Shift) 加速 300% x = x * 2;x = x * 64;//改为:x = x << 1; // 2 ...

  3. ZOJ 1078 Palindrom Numbers

    原题链接 题目大意:判断一个数是不是palindrom.不限于十进制,可以在任何进制下判断. 解法:还好,数字的范围不大,int类型足够搞定.方法就是从2进制开始,先把数字转换成2进制,判断是否对称, ...

  4. boot/setup.S

    !!    setup.S        Copyright (C) 1991, 1992 Linus Torvalds!! setup.s is responsible for getting th ...

  5. poj2762 强连通+拓扑序

    题意:有 n 个房间,不同房间之间有单向通道,问是否任意两个房间 A .B 都可以从 A 到 B 或从 B 到 A(有一条有就可以). 在这题中,如果一些点是在同一个强连通分量中,那么这些点肯定能够相 ...

  6. 越狱Season 1-Episode 4: Cute Poison

    Season 1, Episode 4: Cute Poison [Previously on Prison Break] previously: 以前地 前情提要 -Burrows: I didn' ...

  7. Android项目——网络图片查看器

    效果-=-------------->加入包 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/an ...

  8. OpenCV CommandLineParser 的用法

    OpenCV CommandLineParser 的用法 去百度了一下,关键字:OpenCV CommandLineParser  发现,最多的讲解是:opencv源码解析之(5):CommandLi ...

  9. fs event_socket

    mod_event_socket     Skip to end of metadata   Created by John Boteler, last modified by Niek Vlesse ...

  10. Machine Learning and Data Science 教授大师

    http://www.cs.cmu.edu/~avrim/courses.html Foundations of Data Science Avrim Blum, www.cs.cornell.edu ...