2010年(11)
分类: 嵌入式
2010-06-30 23:49:56
内核是一个不与特定进程相关的功能集合,其内核代码无法轻易在调试器进行,也很难跟踪。
本文简单介绍一下三种在内核环境下监视内核代码并跟踪错误的技术:打印调试、查询调试及监视调试。
首先要做一个准备工作,那就是重新配置自己之前构造的内核使之具有调试功能,因为内核开发者禁止了多项用于调试的功能,那样子可避免这些功能造成额外的输出,导致性能下降。在这里,借鉴了博客Tekkaman Ninja对内核增加如下选项:
Kernel hacking --->
[*] Magic SysRq key
[*] Kernel debugging
[*] Debug slab memory allocations
[*] Spinlock and rw-lock debugging: basic checks
[*] Spinlock debugging: sleep-inside-spinlock checking
[*] Compile the kernel with debug info
[*] Magic SysRq key
Device Drivers --->
Generic Driver Options --->
[*] Driver Core verbose debug messages
General setup --->
[*] Configure standard kernel features (for small systems) --->
[*] Load all symbols for debugging/ksymoops
书上介绍的还有其他配置,有的我不需要,或是s3c2440不支持,菜单里看不见。
一、打印调试
在应用程序中,调用printf显示监视信息。调试内核代码,用printk来完成相同的工作。printk与printf的差别就是,printk通过附加不同的日志级别(loglevel),或者消息优先级所表示的严重程度对消息进行分类。在头文件
KERN_EMERG KERN_ALERT KERN_CRIT KERN_ERR
KERN_WARNING KERN_NOTICE KERN_INFO KERN_DEBUG
|
[root@FriendlyARM /mnt]# ./setlevel 1 [root@FriendlyARM /mnt]# cd /lib [root@FriendlyARM /lib]# insmod hello.ko ;看不到打印消息 [root@FriendlyARM /lib]# rmmod hello [root@FriendlyARM /lib]# cd /mnt [root@FriendlyARM /mnt]# ./setlevel 8 [root@FriendlyARM /lib]# insmod hello.ko ;消息显示出来了 Hello,world [root@FriendlyARM /lib]# rmmod hello Goodbye,world |
/proc/sys/kernel/printk的访问来改变
console_loglevel的值。[root@FriendlyARM /lib]# echo 1 > /proc/sys/kernel/printk [root@FriendlyARM /lib]# insmod hello.ko ;看不到打印消息 [root@FriendlyARM /lib]# rmmod hello [root@FriendlyARM /lib]# echo 8 > /proc/sys/kernel/printk [root@FriendlyARM /lib]# insmod hello.ko ;消息显示出来了 Hello,world [root@FriendlyARM /lib]# rmmod hello Goodbye,world |
int (*read_proc)(char *page,char **start,off_t offset, int count, int *eof, void *data); |
struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode, struct proc_dir_entry *base, read_proc_t *read_proc, void *data); |
void *start(struct seq_file *sfile,loff_t *pos); void *next(struct seq_file *sfile,void *v,loff_t *pos); void *stop(struct seq_file *sfile,void *v); int *show(struct seq_file *sfile,void *v); |
struct seq_operations { void *(*start) (struct seq_file *m, loff_t *pos); void (*stop) (struct seq_file *m, void *v); void * (*next) (struct seq_file *m, void *v, loff_t *pos); int (*show) (struct seq_file *m, void *v); }; |
struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode, struct proc_dir_entry *parent); |