2.sysfs:与procfs类似,由于出现的比较晚,所以它克服了proc的一些缺点,比proc功能更强大。但是由于其文件格式是二进制形式,所以需要特殊工具。该文件系统主要为开发人员提供。
3.其它伪文件系统如:libfs,debugfs等。
在这些文件系统中,proc出现比较早,其实现也很典型。proc最初的设计目的是提供内核和用户交互的平台,使用户可以动态的管理系统,同时获取系统的运行时的信息。在proc中主要的信息便是系统进程信息。
proc_fs.h头文件
在 proc_dir_entry结构体中,定义如下:
- 51struct proc_dir_entry {
-
52 unsigned int low_ino;
-
53 unsigned short namelen;
-
54 const char *name;
-
55 mode_t mode; // 0444
-
56 nlink_t nlink;
-
57 uid_t uid;
-
58 gid_t gid;
-
59 loff_t size;
-
60 const struct inode_operations *proc_iops;
-
61 /*
-
62 * NULL ->proc_fops means "PDE is going away RSN" or
-
63 * "PDE is just created". In either case, e.g. ->read_proc won't be
-
64 * called because it's too late or too early, respectively.
-
65 *
-
66 * If you're allocating ->proc_fops dynamically, save a pointer
-
67 * somewhere.
-
68 */
-
69 const struct file_operations *proc_fops;
-
70 struct proc_dir_entry *next, *parent, *subdir;
-
71 void *data;
-
72 read_proc_t *read_proc; //实现接口函数
-
73 write_proc_t *write_proc;
-
74 atomic_t count; /* use count */
-
75 int pde_users; /* number of callers into module in progress */
-
76 spinlock_t pde_unload_lock; /* proc_fops checks and pde_users bumps */
-
77 struct completion *pde_unload_completion;
-
78 struct list_head pde_openers; /* who did ->open, but not ->release */
-
79};
1.建立目录proc_mkdir
- 148 extern struct proc_dir_entry *proc_mkdir(const char *,struct proc_dir_entry *);
struct proc_dir_entry *:=NULL, 在/proc下新建目录
!=NULL, 表示上级目录
- mydir = proc_mkdir("mydir", NULL);//在/proc目录下新建mydir目录
2.建立文件create_proc_entry()
- 109extern struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode,
-
110 struct proc_dir_entry *parent);
const char *name :文件名称
mode_t mode: 文件权限值 0666 mode_t内核文件权限值 struct proc_dir_entry:若 parent=mydir,在../mydidr/新建文件
若 parent=null, 在 /proc/下 新建文件
- pfile = create_proc_entry("pool", 0666, mydir); 在/proc/mydir/下新建pool文件
3.移除目录或文件remove_proc_entry
- 115 extern void remove_proc_entry(const char *name, struct proc_dir_entry *parent);
const char *name: 要移除的目录或文件的名称
struct proc_dir_entry *parent: 若parent=null,在/proc/删除 目录
若parent!=NULL,删除 ../proc/parent 文件
- remove_proc_entry("pool", mydir); //删除/proc/mydir/下的 pool文件
- remove_proc_entry("mydir",NULL);//删除 /proc/下的mydir目录
我们可以通过cat和echo等文件操作函数来查看和设置这些proc文件。
4.实现proc_dir_entry结构体中 *read_proc函数
- 46typedef int (read_proc_t)(char *page, char **start, off_t off, int count, int *eof, void *data);
- static int myproc_read(char *page, char **start, off_t off, int count, int *eof, void *data)
-
{
-
int len = strlen(msg);
-
if(off >= len)
-
return 0;
-
-
if (count>len-off)
-
count = len - off;
-
-
memcpy(page + off, msg + off, count);
-
return off + count;
-
}
5. 实现proc_dir_entry中 *proc_write函数
- 48typedef int (write_proc_t)(struct file *file, const char __user *buffer, unsigned long count, void *data);
- static int myproc_write(struct file *file, const char __user *buffer, unsigned long count, void *data)
-
{
-
unsigned long count2 = count;
-
if(count2 >= sizeof(msg))
-
count2 = sizeof(msg) - 1;
-
-
if (copy_from_user(msg, buffer, count2))
-
return -EFAULT;
-
-
msg[count2] = '\0';
-
return count;
-
}
例子:
这个例子创建一个 /proc/mydir/pool,它相当于一个池子,你向它写什么,你读它的时候它就返回什么,当然它的容量是有限的 :)
- #include <linux/module.h>
-
#include <linux/init.h>
-
#include <linux/kernel.h>
-
-
#include <linux/proc_fs.h>
-
#include <asm/uaccess.h>
-
-
MODULE_LICENSE("GPL");
-
-
static struct proc_dir_entry *mydir;
-
static struct proc_dir_entry *pfile;
-
-
static char msg[255];
-
-
static int myproc_read(char *page, char **start, off_t off, int count, int *eof, void *data)
-
{
-
int len = strlen(msg);
-
if(off >= len)
-
return 0;
-
-
if (count>len-off)
-
count = len - off;
-
-
memcpy(page + off, msg + off, count);
-
return off + count;
-
}
-
-
static int myproc_write(struct file *file, const char __user *buffer, unsigned long count, void *data)
-
{
-
unsigned long count2 = count;
-
if(count2 >= sizeof(msg))
-
count2 = sizeof(msg) - 1;
-
-
if (copy_from_user(msg, buffer, count2))
-
return -EFAULT;
-
-
msg[count2] = '\0';
-
return count;
-
}
-
-
static int __init myproc_init(void)
-
{
-
mydir = proc_mkdir("mydir", NULL);
-
if(!mydir)
-
{
-
printk(KERN_ERR "Can't create /proc/mydir/n");
-
return -1;
-
}
-
pfile = create_proc_entry("pool", 0666, mydir);
-
if(!pfile)
-
{
-
printk(KERN_ERR "Can't create /proc/mydir/pool/n");
-
remove_proc_entry("mydir", NULL);
-
return -1;
-
}
-
pfile->read_proc = myproc_read;
-
pfile->write_proc = myproc_write;
-
printk("pool init\n");
-
return 0;
-
}
-
-
static void __exit myproc_exit(void)
-
{
-
remove_proc_entry("pool", mydir);
-
remove_proc_entry("mydir", NULL);
-
printk("pool exit\n");
-
}
-
-
module_init(myproc_init);
-
module_exit(myproc_exit);
-
-
//MODULE_LICENSE("GPL");
- obj-m:=pool.o
-
KERNELDIR := /lib/modules/2.6.35-31-generic/build
-
PWD :=$(shell pwd)
-
-
modules:
-
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
-
-
modules_install:
-
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install
-
-
clean:
-
rm -rf *.o *.ko *.mod.c *.order *.symvers
- ywx@ywx:~/desktop/module/proc/pool$ sudo insmod ./pool.ko
-
ywx@ywx:~/desktop/module/proc/pool$ echo "hello linux" > /proc/mydir/pool
-
ywx@ywx:~/desktop/module/proc/pool$ cat /proc/mydir/pool
-
hello linux
-
ywx@ywx:~/desktop/module/proc/pool$ sudo rmmod pool