知识点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
#include
#include
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("[email protected]");
MODULE_VERSION("version 1.0");
#include
#include
#include
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("[email protected]");
MODULE_VERSION("version 1.0");
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
程序输出