(IV .1)是seq_file的實例說明,將Linux中的fp/proc/devices.c拿出來當範例並且予以說明。
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
static int devinfo_show(struct seq_file *f, void *v)
{
int i = *(loff_t *) v;
if (i < CHRDEV_MAJOR_HASH_SIZE) {
if (i == 0)
seq_printf(f, "Character devices:\n");
chrdev_show(f, i);
}
#ifdef CONFIG_BLOCK
else {
i -= CHRDEV_MAJOR_HASH_SIZE;
if (i == 0)
seq_printf(f, "\nBlock devices:\n");
blkdev_show(f, i);
}
#endif
return 0;
}
static void *devinfo_start(struct seq_file *f, loff_t *pos)
{
if (*pos < (BLKDEV_MAJOR_HASH_SIZE + CHRDEV_MAJOR_HASH_SIZE))
return pos;
return NULL;
}
static void *devinfo_next(struct seq_file *f, void *v, loff_t *pos)
{
(*pos)++;
if (*pos >= (BLKDEV_MAJOR_HASH_SIZE + CHRDEV_MAJOR_HASH_SIZE))
return NULL;
return pos;
}
static void devinfo_stop(struct seq_file *f, void *v)
{
/* Nothing to do */
}
static const struct seq_operations devinfo_ops = {
.start = devinfo_start,
.next = devinfo_next,
.stop = devinfo_stop,
.show = devinfo_show
};
static int devinfo_open(struct inode *inode, struct file *filp)
{
return seq_open(filp, &devinfo_ops);
}
static const struct file_operations proc_devinfo_operations = {
.open = devinfo_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release,
};
static int __init proc_devices_init(void)
{
proc_create("devices", 0, NULL, &proc_devinfo_operations);
return 0;
}
module_init(proc_devices_init);
首先,這邊只有module_init(),所以只能載入,不能unload。而載入的點就是create一個proc檔 "devices",並且註冊其file operations "proc_devinfo_operations",在"proc_devinfo_operations"可以發現是一個seq_file的架構,所以我們就會想到start()/next()/stop()/show()等function應該負責的功能。首先會看到start()即"devinfo_start()",可以看出pos代表的是第幾個device,而pos最大為block+char的總和。
"devinfo_next()"應該負責移動pos,所以可以看出只有做了(*pos)++。
由於"devinfo_start()"並沒有和系統要求任何的resource,所以"devinfo_stop()"就不需要有任何cleanup的動作。
而"devinfo_show()"則是各別呼叫"chrdev_show()"和"blkdev_show()"來顯示char device和block device。

沒有留言:
張貼留言