所有代码都在 2.6.29-gentoo-r5 中调试并通过.
传说中学习必备的 helloworld 例子.
#include <linux/init.h> #include <linux/module.h> MODULE_LICENSE("Dual BSD/GPL"); static int hello_init(void) { printk(KERN_ALERT "Hello, KKernel !\n"); return 0; } static void hello_exit(void) { printk(KERN_ALERT "Goodbye, KKernel!\n" ); } module_init(hello_init); module_exit(hello_exit);
1、Makefile书写:
PWD = $(shell pwd)
#1 obj-m := hello.o 模块只有一个文件
#2 hello-objs := one.o two.o three.o 模块有多个文件
#3 如果模块是由一个目录(online)组成的写法如下
a、在这个目录的上一级目录中的makefile中加入
obj-m += online/ #告诉在编译的时候找到online目录
obj-$(CONFIG_USB_GADGET_ONLINE) += online/ 这种方式是用配置选项(kconfig文件中添加配置选项)来判断是否编译这个子目录(即模块)
b、最后,我们在online/下创建新文件Makefile,并且添加下面一行到其内。
netmeeting-objs := one.o two.o three.o 如果有多个文件
all:
[TAB] $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
clean:
[TAB] rm -rf *.o *.ko *.mod.c *.o.cmd .tmp_versions *.mod.o .cmd
2、编译运行 超级用户
insmod
rmmod
lsmod
3、调试查看输出信息
a、在模块中添加调试输出语句 printk
dmesg (syslogd进程已经运行 /etc/rc.d/init/rsyslog 开启)
cat /var/log/message
注意:
宏的定义等级如下(printk.c):
#define KERN_EMERG “<0>” /* system is unusable */
#define KERN_ALERT “<1>” /* action must be taken immediately */
#define KERN_CRIT “<2>” /* critical conditions */
#define KERN_ERR “<3>” /* error conditions */
#define KERN_WARNING “<4>” /* warning conditions */
#define KERN_NOTICE “<5>” /* normal but significant condition */
#define KERN_INFO “<6>” /* informational */
#define KERN_DEBUG “<7>” /* debug-level messages */
当指定的等级小于console_level(默认4)时候,就可以直接在tty上面打印输出语句
console_level设置方式:
通过对/proc/sys/kernel/printk的访问来改变console_loglevel的值:
jimi@gentoo ~/myldd3/hello $#cat /proc/sys/kernel/printk
1 4 1 7
jimi@gentoo ~/myldd3/hello $ ]#insmod hello.ko
jimi@gentoo ~/myldd3/hello $ #rmmod hello
jimi@gentoo ~/myldd3/hello $ #echo 7 > /proc/sys/kernel/printk
[jimi@gentoo ~/myldd3/hello $#cat /proc/sys/kernel/printk
7 4 1 7
[Tekkaman2440@SBC2440V4]#insmod hello.ko
Hello, KKernel !
[Tekkaman2440@SBC2440V4]#rmmod hello
Goodbye, KKernel!
四个数字的含义:当前的loglevel、默认loglevel、最小允许的loglevel、引导时的默认loglevel。