第一个helloworld内核模块
1 源码:
first_mod.c
/*
first_mod.c
My first kernel module.
*/
#include <linux/module.h> /* Needed by all modules */
#include <linux/kernel.h> /* Needed for KERN_INFO*/
MODULE_LICENSE("Dual BSD/GPL");//不加报错[16921.551127] first_mod: module license 'unspecified' taints kernel.
static int hello_init(void)
{
//在内核中打印时,不能使用print,而是printk 和print相比,多了一个优先级
printk(KERN_INFO "Hello world.\n");
// A non 0 return means init_module failed; module can't be loaded.
return 0;
}
static void hello_exit(void)
{
printk(KERN_INFO "Goodbye world.\n");
}
module_init(hello_init);
module_exit(hello_exit);
装载时(insmod),调用module_init(…)中说明的函数。
卸载时(rmmod),调用module_exit(…)中说明的函数。
方法名不能叫init_module,搞不懂。方法没有参数需要添加 void。
Makefile:
obj-m := first_mod.o
CURRENT_DIR :=$(shell pwd)
KERNEL_DIR := /usr/src/linux-headers-$(shell uname -r)
#KERNELDIR:=/lib/modules/$(shell uname -r)/build
all:
$(MAKE) -C $(KERNEL_DIR) M=$(CURRENT_DIR) modules
clean:
rm -f *.o *.ko *.order *.symvers
#make -C $(KERNELDIR) M=$(PWD) clean
需要注意的是Makefile第一个字母大写,而且文件名最后不能有空格(自己不小心加了个空格)。
错误: makefile:7: * missing separator. Stop.
在Makefile文件中,命令必须以【tab】键开始。不能以几个空格代替。
obj-y 是编译到内核,obj-m是编译成模块,
赋值语句 “=”和”:=”的区别:
1、“=”
make会将整个makefile展开后,再决定变量的值。也就是说,变量的值将会是整个makefile中最后被指定的值。看例子:
x = foo
y =
(x)barx=xyz在上例中,y的值将会是xyzbar,而不是foobar。2、“:=”“:=”表示变量的值决定于它在makefile中的位置,而不是整个makefile展开后的最终值。x:=fooy:=
(x) bar
x := xyz
在上例中,y的值将会是 foo bar ,而不是 xyz bar 了。
CURRENT_DIR和KERNEL_DIR是定义两个变量。
CURRENT_DIR就是pwd的结果,也就是当前目录;
KERNEL_DIR是linux kernel的源码目录,
all和clean是2个目标(target).
2
执行make:
make
生成first_mod.ko等几个文件。
加载模块:
sudo insmod first_mod.ko
加载后无信息输出代表正确。
lsmod 查看到加载的module。
dmesg查看模块运行信息:
dmesg
会输出Hello world.字符串,授权失败那些不管。
卸载模块:
sudo rmmod first_mod
lsmod 查看到加载的module已经不见。
参考:
http://www.cnblogs.com/main-xlg/p/4042667.html
Makefile学习:
http://blog.csdn.net/ruglcc/article/details/7814546/
http://blog.csdn.net/haoel/article/details/2886/