【基本知识】printk,模块机制

知识点1:使用命令cat /proc/sys/kernel/printk可查看当前系统的的printk的级别值(4 4 1 7),其中数值越小,级别越高;第一个值,表示控制台日志级别;第二个值是用该优先级打印没有注明级别的消息;第三个值是指控制台日志可被设置的小值;第四个值是缺省的控制台日志级别;可在/var/log/syslog或/var/log/messages中查看,或使用dmesg来查看,现在ubuntu一般控制台都不输出这些信息,由init进程转接给日志文件;


知识点2:在我们insmod kk.ko时内核会初始化,申请资源,而rmmod kk时,一定要在模块的退出函数中,一定要撤销初始化函数所做的一切,否则在系统重新引导之前某些东西就会在系统中;


知识点3:无论在内核程序和应用程序中,栈是用来保存函数调用历史以及当前活动函数的自动变量的,但是在内核中栈非常小,比如4kb这样的页面大小,我们的函数是和整个内核空间共享这个链的,因此申明大的自动变量是不好的;


知识点4:在模块有前后依赖关系的时候,如果rmmod被依赖的模块会报错;


知识点5:内核中的可靠性是至关重要的,初始化过程成的出错处理,内核源代码中大量使用了goto语句,主要是因为它的高效;应用程序中,我们是可以避免goto语句的;


知识点6:使用static,可以是的函数的作用域在本文件;


知识点7:仅仅是申明使用外来文件定义的x,而去掉extern,那就是本文件的x;如果没有文件导出x,那么在insmod会出现unkonwn symbol的错误;


程序实现

module1.c

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

int x = 10;
/*
	知识点1:使用命令cat /proc/sys/kernel/printk可查看当前系统的的printk的级别值(4 4 1 7),其中数值越小,级别越高;
	第一个值,表示控制台日志级别;第二个值是用该优先级打印没有注明级别的消息;第三个值是指控制台日志可被设置的小值;第四个值是缺省的控制台日志级别;可在/var/log/syslog或/var/log/messages中查看,或使用dmesg来查看,现在ubuntu一般控制台都不输出这些信息,由init进程转接给日志文件;
	知识点2:在我们insmod kk.ko时内核会初始化,申请资源,而rmmod kk时,一定要在模块的退出函数中,一定要撤销初始化函数所做的一切,否则在系统重新引导之前某些东西就会在系统中;
	知识点3:无论在内核程序和应用程序中,栈是用来保存函数调用历史以及当前活动函数的自动变量的,但是在内核中栈非常小,比如4kb这样的页面大小,我们的函数是和整个内核空间共享这个链的,因此申明大的自动变量是不好的;
	知识点4:在模块有前后依赖关系的时候,如果rmmod被依赖的模块会报错;
	知识点5:内核中的可靠性是至关重要的,初始化过程成的出错处理,内核源代码中大量使用了goto语句,主要是因为它的高效;应用程序中,我们是可以避免goto语句的;

*/
static void add(int a, int b)
{
	printk("Default Hello Linux %d + %d + %d = %d\n", a, b, x, a + b + x);
}

static int hello_init(void)
{
	printk(KERN_EMERG "KERN_EMERG Here I am IN%s  %s %i\n",__FILE__,__FUNCTION__,__LINE__);
  	printk(KERN_ALERT "KERN_ALERT Hello Linux %s  %s %i\n",__FILE__,__FUNCTION__,__LINE__);
	printk(KERN_CRIT "KERN_CRIT Hello Linux\n");
	printk(KERN_ERR "KERN_ERR Hello Linux\n");
	printk(KERN_WARNING "KERN_WARNING Hello Linux\n");
	printk(KERN_NOTICE "KERN_NOTICE Hello Linux\n");
	printk(KERN_INFO "KERN_INFO Hello Linux\n");
	printk(KERN_DEBUG "KERN_DEBUG Hello Linux\n");
	printk("Default Hello Linux\n");
	printk(KERN_ALERT "KERN_ALERT The process is %s  %i\n", current->comm, current->pid);	//打印出当前进程所执行程序文件的基本名称以及进程号;
	
	add(2, 10);
  	return 0;
}

static void hello_exit(void)	//使用static,可以是的函数的作用域在本文件
{

}

EXPORT_SYMBOL_GPL(x);		//导出符号x
EXPORT_SYMBOL_GPL(add);		//导出函数add

module_init(hello_init);
module_exit(hello_exit);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("module");
MODULE_AUTHOR("uppour@sina.cn");
MODULE_VERSION("version 1.0");

module2.c

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

extern int x;		//仅仅是申明使用外来文件定义的x,而去掉extern,那就是本文件的x;如果没有文件导出x,那么在insmod会出现unkonwn symbol的错误;

int y;

extern int add(int, int);

static char *whom = "world";
static char *whom2 = "hello";

static int hello_init(void)
{
	add(6, 20);
	printk("Default Hello Linux %d ,%d ,%s, %s\n", x, y, whom, whom2);
  	return 0;
}

static void hello_exit(void)	//使用static,可以是的函数的作用域在本文件
{
	
}

module_param(whom, charp, S_IRUGO);	//允许任何用户,模块参数

module_init(hello_init);
module_exit(hello_exit);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("module");
MODULE_AUTHOR("uppour@sina.cn");
MODULE_VERSION("version 1.0");

Makefile

obj-m += module1.o module2.o

KERN_DIR := /lib/modules/2.6.32-62-generic/build

all:
	make -C $(KERN_DIR) M=`pwd` modules

clean:
	make -C $(KERN_DIR) M=`pwd` modules clean
	rm -rf modules.order

程序输出


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值