Linux设备驱动程序(第三版)学习之内核的调试技术(三)_2_查询调试

本文探讨了printk函数可能带来的系统性能问题,并介绍了如何通过配置syslog.conf来优化。此外,深入讲解了/proc文件系统的工作原理及其在Linux系统中的应用,包括如何创建和读取/proc下的文件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先说一说printk函数给系统带来的一些缺点

******大量使用printk能够显著拖慢系统,因为syslogd进程会不停滴同步系统的输出文件,也就是说,printkh函数每打印一行就会引发一次向磁盘的写操作

******解决这个问题的办法是对于在/etc/syslog.conf中的日志文件在其前面加一个连字符或者一个减号“-”来阻止syslogd进程将每个消息刷新文件到磁盘.

例如:

daemon.*			-/var/log/daemon.log
kern.*				-/var/log/kern.log
lpr.*				-/var/log/lpr.log
mail.*				-/var/log/mail.log
user.*				-/var/log/user.log

最好获得相关信息的方法是系统查询,在你想要查看系统的某一消息的时候,不希望系统总是不停的产生消息,而是获取某一是个的系统消息,Linux系统提供的诸如ps,netstat等工具

***提供给驱动开发者用来查询系统的几个技术

介绍一下/proc文件系统

***1. /proc文件系统是由软件创建的特殊的文件系统,内核向外界输出的消息就在这个文件系统里.

***2. /proc下的每个文件都绑定到了一个内核函数上了,当读这些文件时就会立刻能产生文件的内容,例如/proc/modules,读取该文件可以查看插入到内核的模块.

***3. 对于很多Linux工具,如ps,top,uptime等都是从/proc中获取它们的信息.

***4. 对于一些驱动设备来说也通过/proc输出信息,因此对于自己编写的驱动也可以向/proc输出信息

***5. /proc文件系统是动态的,因此你的模块可以在任何时候添加条目或去除条目(即你的驱动输出文件)

***6. /proc下的文件可写可读,但是大部分是只读的文件.

1. 在/proc文件系统下实现创建的文件的内容的函数.

在头文件<linux/proc_fs.h>中对read,write函数的定义.

typedef	int (read_proc_t)(char *page, char **start, off_t off,int count, int *eof, void *data);
typedef	int (write_proc_t)(struct file *file, const char __user *buffer,unsigned long count, void *data);
read_proc_t *read_proc;
write_proc_t *write_proc;

即是:

int (*read_proc)(char *page, char **start, off_t offset, int count, int *eof, void *data);

****a. 对于用户来说,当有一个进程读你在/proc文件下创建的文件时,内核就会给你创建的文件分配一页内存(PAGE_SIZE字节)
****b. 可以将驱动写入到缓冲区page的数据通过函数read_proc返回给用户空间

****c. read_proc的参数说明

***********page------------------>写数据的缓冲区

***********start------------------->用于指定写入页中数据的起始位置,当start设定为NULL时,内核假定数据已经放进page偏移是0,也就是内核将整个徐宁文件的内容放到了page.

***********offset------------------>相对于起始位置的偏移量

***********count------------------>写如数据的总数

***********eof--------------------->驱动用于对用户设置文件结束标志的

**********data--------------------->驱动特定的数据指针,可以用作内部用途.

**********返回值------------------>返回page缓冲区实际的字节数.

2. 在/proc文件中创建你自己的文件

****将自己实现的read_proc函数连接到/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)
****参数解析

*************name------------------------------>要在/proc下创建的文件名字

*************mod-------------------------------->创建的文件的访问权限,默认是0

*************base------------------------------->指出创建的文件所在的目录,若base是NULL,文件在/proc下创建

*************read_proc------------------------>自己实现的read_proc函数

*************data-------------------------------->传递给read_proc函数的参数,被内核忽略.

3. 当模块被卸载时,移除在/proc下创建的文件

void remove_proc_entry(const char *name, struct proc_dir_entry *parent);


在/poc目录下创建Dediprog文件的模块源代码如下

#include <linux/module.h>
//#include <linux/init.h>
#include <linux/proc_fs.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Bruce.Wang");
MODULE_VERSION("1.0");
MODULE_DESCRIPTION("Test the proc_read in the /proc");

/**
  *Achieve your own read_proc
  **/
int my_read_proc(char *page, char **start, off_t offset, int count, int *eof, void *data)
{
	int ret = 0;
	ret += sprintf(page, "Hello guys,My name is Bruce,I'm from function %s of the module\n",__FUNCTION__);
	ret += sprintf(page+ret, "%s\n",(char *)data);
}

static int __init my_read_proc_init(void)
{
	char *info = "Hello I'm here, from the create_proc_read_entry in  my_read_proc_init function";
	/**
	  *create a file of Dediprog in the /proc
	  **/
	create_proc_read_entry("Dediprog", 0444, NULL,my_read_proc, info);
	return 0;
}
module_init(my_read_proc_init);

static void __exit my_read_proc_exit(void)
{
	remove_proc_entry("Dediprog", NULL);
	printk("Module proc_read Bybe\n");
}
module_exit(my_read_proc_exit);
读取/proc/Dediprog文件的内容,你可以自己编写一个app应用程序读取也可执行[root@linux ~] # cat /proc/Dediprog   ------->查看


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值