先说一说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);
#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 ------->查看