个人笔记。。在不放过来都快找不到了。有空还得好好整理一下了。
调试方法
printk() 是用来调试内核最常用的一种技术,他打印的信息会输出在 dmesg 中,所以调试前最好使用 dmesg -c 来清掉以前 dmesg 的信息。 使用的例子如下:
printk(KERN_DEBUG "Here i am:%s:%d\n", FUNCTION, LINE);
可以打印的级别可以看看 linux/kernel.h 中的定义。 strace 这个命令超级强大,可以显示程序所有的系统调用,还可以显示调用时使用的参数。 但这个时候不需要麻烦的配置就可以直接使用,但不能象 gdb 调试 c 程序一样,所以内核为我们提供了一个 kdb ,可以支持动态修改变量,断点设置,单步执行
kernel oops messages
这是内核开发时常会出现的一个错误信息。主要原因是由于 NULL 指针引用,和其它不正常的指针操作引起的。这时 oops 会显示故障时的处理器信息, 模块 CPU 寄存器内容,页描述符表的位置之类的信息。
内核模块简单介绍
模块是工作在内核空间的 模块实际是目标文件(由函数和数据结构组成),不象普通程序有个链接的过程,不能独立运行,只能在运行时链接到系统做为内核的一部分运行,从面扩展内核功能 内核模块会占用内核空间的内存,所以会影响内存使用,它还会修改内核中的一些内容,所以容易造成系统挂掉。在内核中需要维护符号表。并且内核之间有依赖性。
最简单的内核模块
注:如果是 redhat 安装的话,需要安装 kernel-devel 才能写内核模块,如果是自己编译内核,记的不要删除源码,不然没法开发模块。
#include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> /* __init 的标记是内核模块的入口,这个函数加载完后就会释放内存空间 */ static int __init hello_init( void ) { printk(KERN_INFO "Hello world" ); /* 打印的信息会出现在 dmesg 中 释放*/ return 0; /* 返回 0 是正常 */ } /* __exit 的标记是退出内核模块,当这个模块卸载时会执行 */ static void __exit hello_exit( void ) { printk(KERN_INFO "Goodbye world" ); } /* 下面这二个是宏,初始化和消除函数时使用和上面的装载卸载模块没关系。 */ module_init(hello_init); module_exit(hello_exit); |
原文转自:http://blogread.cn/it/article/4630