1. printk
好用优点多,缺点是可能丢失数据、量大时影响性能。
原理是将消息写入到一个__LOG_BUF_LEN字节的循环缓冲区中,并唤醒以下两类进程:
在syslog系统调用上睡眠的、或对/proc/kmsg读取的进程,比如klogd。对/proc/kmsg读取操作后,缓冲区中的数据不再存在了。klogd一般获取数据后,会发给syslogd,后者通过配置/etc/syslog.conf来处理这些数据。
2. /proc
是软件创建的特殊文件系统,每个文件绑定于一个内核函数,读文件时,内核函数被触发,从内核返回数据到用户空间,造成“读”文件的假像。
第一种实现:
创建文件要调用这个接口:
-
struct proc_dir_entry *create_proc_read_entry(const char *name,mode_t mode, struct proc_dir_entry *base, read_proc_t *read_proc, void *data);
其中,base为所在目录,默认为/proc;name即为文件名。
read_proc是一个函数,就是它实现了从内核中往用户空间拷贝数据,如下:
-
int (*read_proc)(char *page, char **start, off_t offset, int count, int *eof, void *data);
char * page的参数传进来,这就是要拷回给用户空间的内存页。
第二种实现:
用另一个创建接口来建立实际/proc文件:
-
entry = create_proc_entry("scullseq", 0, NULL);
再将对应的seq操作与seq_open调用的file联系起来,就可以通过seq_file实现/proc文件了:
-
static struct file_operations scull_proc_ops = {
-
.owner = THIS_MODULE,
-
.open = scull_proc_open,
-
.read = seq_read,
-
.llseek = seq_lseek,
-
.release = seq_release
-
};
-
-
static int scull_proc_open(struct inode *inode, struct file *file)
-
{
-
return seq_open(file, &scull_seq_ops);
-
}
总体来说不鼓励使用/proc,因为:
1) 如果调用remove_proc_entry删除对应的目录项失败,会有问题;
2) 如果注册时,创建了两个相同的目录项,那么访问和删除时,都会有问题。
3. ioctl
可以设计一些专门的ioctl调试命令来帮助调试。与/proc比优点:
1) 驱动程序端编码较容易;
2) 读速度比/proc快;
3) 是隐密的,不公开的。不像/proc中一堆文件大家都不清楚是什么。
小缺点:需要开发客户端的读取程序,导致模块大一点。
4. 处理挂起问题
1) 真挂起,可在驱动程序中适当处显式schedule。注意有坑,schedule需要考虑可重入。万不可带自旋锁否则可能死锁;
2) 假挂起,sysrq魔法键。
5. 用户模式的linux虚拟机
它是运行在linux之上的一个做为用户进程的linux内核,调试有一定好处。
阅读(653) | 评论(0) | 转发(0) |