内核模块编写 编译 加载/查看/删除模块

#include <linux/init.h>
#include <linux/module.h>

static int __init hello_init(void)
{
 printk(KERN_EMERG "ha");
 return 0;
}
static void hello_exit(void)
{
 printk("le");
} 
module_init(hello_init);
module_exit(hello_exit);

__init 表示初始化程序段 ,运行完后,系统就会回收内存空间

Makefile 文件

ifneq ($(KERNELRELEASE),)
obj-m := hello.o
else 
KDIR := /lib/modules/2.6.31-14-generic/build
all :
 make -C $(KDIR) M=$(PWD) modules
clean:
 rm -f *.ko *.o *.mod.c *.symvers
endif

编译模块 #make  

产生hell0.ko

添加hello 模块 # insmod hello.ko

查看hello 模块 #lsmod 

删除hello 模块 #rmmod hello

注意:模块操作以root身份运行


模块应用参数

MODULE_PARAM(name(名称),type(类型),perm(访问权限))

type常见值:bool   int     charp(字符串)

如int a = 1;

    char *st;

    module_param(a,int,S_IRUGO);

    module_param(st,charp,S_IRUGO);

#include <linux/init.h>
#include <linux/module.h>

static char *name = "chen";
static int age = 30;

module_param(age, int, S_IRUGO);
module_param(name, charp, S_IRUGO);

static int hello_init(void)
{
  printk(KERN_EMERG "name:%s\n",name);
  printk(KERN_EMERG "age:%d\n",age);
  return 0;
}
static void hello_exit(void)
{
 printk("le");
} 
module_init(hello_init);
module_exit(hello_exit);

控制台优先级 决定模块里的printk()能否打印出来

vi   /proc/sys/kernel/printk 可以查看 级别 控制台 默认级别 最小级别

printk() 有8个级别 

#define KERN_EMERG 0/*紧急事件消息,系统崩溃之前提示,表示系统不可用*/
#define KERN_ALERT 1/*报告消息,表示必须立即采取措施*/
#define KERN_CRIT 2/*临界条件,通常涉及严重的硬件或软件操作失败*/
#define KERN_ERR 3/*错误条件,驱动程序常用KERN_ERR来报告硬件的错误*/
#define KERN_WARNING 4/*警告条件,对可能出现问题的情况进行警告*/
#define KERN_NOTICE 5/*正常但又重要的条件,用于提醒*/
#define KERN_INFO 6/*提示信息,如驱动程序启动时,打印硬件信息*/
#define KERN_DEBUG 7/*调试级别的消息*/

默认级别与printk级别决定 是否可以显示出来(纯字符模式等级低,可以到纯字符模式,查看打印效果,或者修改上面的问件)

编译多个文件 Makefile

ifneq ($(KERNELRELEASE),)
obj-m := hello.o
hello-objs := main.o add.o

else

KDIR :=	/lib/modules/2.6.31-14-generic/build
all:
	make -C $(KDIR) M=$(PWD) modules
clean:
	rm -f *.ko *.o *.mod.c  *.symvers

endif

//  main.c
#include <linux/module.h>
#include <linux/init.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("chen");
MODULE_DESCRIPTION("a simple module");

extern int add(int a,int b);
static int hello_init()
{
	printk(KERN_EMERG "hello \n");
	add(1,2);
	return 0;
}

static void hello_exit()
{
	printk(KERN_EMERG "ok\n");
}

module_init(hello_init);
module_exit(hello_exit);

//  add.c
int add(int a,int b)
{
	return a+b;
}

一个模块依赖另一个模块函数时EXPORT_SYMBOL(依赖函数)

// 模块 add.ko
#include <linux/init.h>
#include <linux/module.h>

int add(int a,int b)
{
	return a+b;
}

static int __init sym_init()
{
	return 0;
}

static void __exit sym_exit()
{
}

EXPORT_SYMBOL(add); //模块之间传递函数

module_init(sym_init);
module_exit(sym_exit);

// 模块 hello.ko
#include <linux/module.h>
#include <linux/init.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("chen");
MODULE_DESCRIPTION("a simple module");

extern int add(int a,int b);
static int __init hello_init()
{
	printk(KERN_EMERG "hello \n");
	int sum = add(1,2);
	return 0;
}

static void __exit hello_exit()
{
	printk(KERN_EMERG "ok\n");
}

module_init(hello_init);
module_exit(hello_exit);

ifneq ($(KERNELRELEASE),)
obj-m := hello.o  ;这里分别写add.o和hello.o编译两个模块

else

KDIR :=	/lib/modules/2.6.31-14-generic/build
all:
	make -C $(KDIR) M=$(PWD) modules
clean:
	rm -f *.ko *.o *.mod.c  *.symvers

endif


你可能感兴趣的:(编译,内核模块编写,加载/查看/删除模块)