Chinaunix首页 | 论坛 | 博客
  • 博客访问: 340293
  • 博文数量: 40
  • 博客积分: 826
  • 博客等级: 准尉
  • 技术积分: 727
  • 用 户 组: 普通用户
  • 注册时间: 2011-07-22 15:18
文章分类

全部博文(40)

文章存档

2016年(1)

2015年(1)

2013年(12)

2012年(5)

2011年(21)

分类: LINUX

2011-08-03 09:12:04

Makefile:

#ifneq($(KERNELRELEASE),)
obj-m := hello.o
#else

KERNELDIR := /usr/src/linux/

modules:
    $(MAKE) -C $(KERNELDIR) SUBDIRS=$(PWD) $@
install:
    insmod hello.ko
uninstall:
    rmmod hello.ko
clean:
    rm -rf *.ko *.o *.mod.c *.symvers *.order

/* ===================================================================================
    上述makefile开始执行的时候,为定KERNELDIR义,所以为空,#ifneq($(KERNELRELEASE),)不成立,执行
    else分支,执行到$(MAKE) -C $(KERNELDIR) SUBDIRS=$(PWD) $@ 的时候,make 离当前路径,到
    KERNELDIR := /usr/src/linux/ kernel路径下读取相关的配置文件信息,之后回到当前目录下再次从
    头执行makefile 文件,这个时候KERNELRELEASE 已经定义,不为空,那就执行
obj-m := hello.o命令
    生成我们的目标.KO文件.
 ===================================================================================*/

module example:

/*
 * =====================================================================================
 *
 *       Filename:  hello.c
 *
 *    Description:  dragon
 *
 *        Version:  1.0
 *        Created:  2011年08月02日 03时02分35秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  YOUR NAME (),
 *        Company: 
 *
 * =====================================================================================
 */

#include
#include

static char *param1 = "param1\n";
static int param2 = 2;

module_param(param1, charp, S_IRUGO);
module_param(param2, int, S_IRUGO);

MODULE_LICENSE("GPL"); /* 必不可少*/

/* 下面的信息是模块详细信息,作者自己根据喜好可增加,目的便于
    使用该模块的用户能用诸如modinfo了解该模块的相关信息*/
MODULE_AUTHOR("dragon");              
MODULE_DESCRIPTION("module learning");
MODULE_ALIAS(" test module");
MODULE_VERSION("2.6.27");

int exportsymbol_test(void)
{
    printk("export symbol test\n");
    return 0;
}

EXPORT_SYMBOL_GPL(exportsymbol_test);
//EXPORT_SYMBOL(exportsymbol_test);

static int __init hello_init(void)
{
    printk("hello init\n");
    printk("param1:%sparam2:%d\n", param1, param2);
    return 0;
}

static  void __exit hello_exit(void)
{
    printk("hello exit\n");
    printk("param1:%sparam2:%d\n", param1, param2);
    return;
}
   
module_init(hello_init);
module_exit(hello_exit);
     /* ===================================================================================
        知识小结:
        1. module_param(参数,类型,权限)
        参数(param):变量的名称;
        类型(type):变量的类型,包括int,char, charp...;
             
        如果模块以本接口定义了参数,那么:
        a) 在insmod 或者 modprobe 加载模块的过程中带有 param=value,那么该param将用外部的value
           值取代默认的param值, 否则保持默认值;
        b)如果模块在使用了本接口定义了外部接口参数,那么在/proc/modules 文件中会有本模块的加
           载信息,同时在/sys/module/模块/ 下的相关子目录下生成有对应的param子目录。例如,如果
           定义了module_param(num, int, S_IRUGO), 那么在/sys/module/模块的/moduleparams/ 下生成
           有num的文件(这个示不同的linux版本而定),这个文件的值便是该参数模块中的取值。

 
        权限(priority): 正如上述所示,权限指的便是在用户模式下对应的/sys/module/moduleparams/param
                        文件的访问权限, 因此可知,根据该权限的设置,可以决定应用层能否对模块的运行
                        参数进行配置。权限有如下的选项:
                        S_IRUGO: 只读;
                        S_IWUGO: 可写;
                        S_IXUGO: 未知;
                        S_IALLUGO: 包括上述所有的权限;
                        S_IRWXUGO: 同上;
      
       2. EXPORT_SYMBOL_GPL(参数) / EXPORT_SYMBOL(参数);
        上述的两个宏主要是用来导出符号到/proc/kallsyms 文件中,该文件中包含有导出的符号名称和对应的
        内存地址。参数中一般是函数名,这样在其他的内核模块中申明后就可以使用该函数,当然,其他的类型
        参数同理。
       3. 模块的依赖文件:
         如果是单一的文件,一般是用
                obj-m: 模块.ko;
         如果是模块依赖多个文件,那么使用:
               obj-m: 模块.ko;
               module-objs: file1.o file2.o ... filen.o
       4. 模块的注册和注销
         模块中是必须使用module_init()和module_exit()分别注册模块的加载函数和退出函数,至于该模块使用
         的__init 和 __exit标识,这只是linux 系统的特被标识,以便linux系统在进行相应的操作时候进行
         相关的特殊处理,详细的内容会在其他文章叙述。
         ================================================================================*/
                


阅读(1010) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~