Chinaunix首页 | 论坛 | 博客
  • 博客访问: 70708
  • 博文数量: 12
  • 博客积分: 277
  • 博客等级: 二等列兵
  • 技术积分: 130
  • 用 户 组: 普通用户
  • 注册时间: 2011-10-01 02:45
文章分类

全部博文(12)

文章存档

2011年(12)

我的朋友

分类: 嵌入式

2011-10-31 13:04:52

内核模块具有如下特点:
1、模块本身并不编译进内核文件;2、可以根据需要,在内核运行期间动态地安装或卸载。
模块操作:
加载模块:insmod hello.ko
卸载模块:rmmod hello
查看内核模块:lsmod
加载模块的另一种方式:modprobe hello
modprobe与insmod的不同之处在于它会根据文件/lib/modules/<$version>/modules.dep来查看要加载的模块,看它是否还依赖于其他模块,
如果是,modprobe会先首先找到这些模块,把它们加载到内核。
一、最简单的模块代码:
#include
#include
MODULE_LICENSE("GPL");   ---》许可证声明
MODULE_AUTHOR("David Xie");
MODULE_DESCRIPTION("Hello World Module");
MODULE_ALIAS("a simplest module");
static int __init hello_init()
{
    printk(KERN_EMERG"Hello World!\n");
    return 0;
}
static void __exit hello_exit()
{
    printk("<6>hello exit\n");
}
module_init(hello_init);
module_exit(hello_exit);
单源文件makefile:
ifneq ($(KERNELRELEASE),)   --》第一次编译的时候,KERNELRELEASE为空,所以执行else里的语句,第二次开始则不为空
obj-m := hello.o     --》hello.o与hello.c对应
else 
KDIR := /lib/modules/2.6.18-53.el5/build
all:
 make -C $(KDIR) M=$(PWD) modules  --》-C的意思是进入KDIR,使用这个目录下的makefile;m=$(PWD)的意思是要编译的模块在当前目录
clean:
 rm -f *.ko *.o *.mod.o *.mod.c *.symvers
endif
以上为x86平台下的实现,若为arm平台则:make -C $(KDIR) M=$(PWD) modules ARCH=arm CROSS_COMPILE=arm-linux-
多源文件makefile:
假设两个源文件,main.c和add.c,则改变上面makefile中的两行,其他不变
obj-m := hello.o
hello-objs := main.o add.o
二、模块参数
例子:
#include                                
#include                                
MODULE_LICENSE("GPL");
        
static char *name = "David Xie";             
static int age = 30;   
module_param(age, int, S_IRUGO);     --》用于在加载模块时给模块传递参数                          
module_param(name, charp, S_IRUGO);   --》第一个参数是模块参数的名称,第二个是类型(int,bool,charp),
       第三个是模块参数的访问权限(S_IRUGO--任何用户都对/sys/module出现的该参数有读权限,
            S_IWUSR,允许root修改/sys/module中出现的该参数)                         
static int hello_init(void)                               
{                               
 printk(KERN_EMERG" Name:%s\n",name);                       
 printk(KERN_INFO" Age:%d\n",age);                              
 return 0;                               
}                               
static void hello_exit(void)                               
{                               
 printk(KERN_INFO" Module Exit\n ");                           
}
                               
module_init(hello_init);                               
module_exit(hello_exit);      
insmod时若无加参数,则为代码里设定的值,若要添加参数,则格式为:insmod param.ko name=... age =... 注意类型要对应
三、内核符号导出,模块之间存在依赖时使用
EXPORT_SYMBOL(符号名)、EXPORT_SYMBOL_GPL(符号名),其中后者只能用于包含GPL许可证的模块
模块一:hello.c
#include
#include
MODULE_LICENSE("GPL");
MODULE_AUTHOR("David Xie");
MODULE_DESCRIPTION("Hello World Module");
MODULE_ALIAS("a simplest module");
extern int add_integar(int a,int b);   --》在模块二中定义
extern int sub_integar(int a,int b);
static int __init hello_init()
{
    int res = add_integar(1,2);
    return 0;
}
static void __exit hello_exit()
{
    int res = sub_integar(2,1);
}
module_init(hello_init);
module_exit(hello_exit);
模块二:calc.c
#include                                
#include
                              
MODULE_LICENSE("GPL");                               
                               
int add_integar(int a,int b)                               
{                               
 return a+b;                            
}
                              
int sub_integar(int a,int b)                               
{                               
 return a-b;                            
}                           
static int __init sym_init()
{
    return 0;
}
static void __exit sym_exit()
{
}
module_init(sym_init);
module_exit(sym_exit);
/* EXPORT_SYMBOL(add_integar); */   --》这两句要添加才能使用hello.ko模块,这个模块要先安装,再安装hello.ko模块,卸载时相反
/* EXPORT_SYMBOL(sub_integar); */

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