通过proc文件系统输出必要的Linux内核信息(下)

  

    3、使用seq_file接口的例子

    本例通过/proc/seq_file_test文件输出Linux内核的十个随机数,并与printk打印的信息进行比较。

    (1)、例子源代码 

#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/random.h>
#include <linux/slab.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/list.h>

struct mylist_random {
    struct list_head list;
    char info[50];
};

static LIST_HEAD(test_list);

static void *seq_start(struct seq_file *m, loff_t *pos)
{
    return seq_list_start(&test_list, *pos);;	
}

static void seq_stop(struct seq_file *m, void *v)
{
    /* No cleanup needed in this example */
}

static void *seq_next(struct seq_file *m, void *v, loff_t *pos)
{
    return seq_list_next(v, &test_list, pos);
}

static int seq_show(struct seq_file *m, void *v)
{
    const struct mylist_random *p = list_entry(v, struct mylist_random, list);
    
    seq_printf(m, "%s", p->info);
		
    return 0;
}

static const struct seq_operations seq_test_ops = {
	.start  = seq_start,
	.next   = seq_next,
	.stop   = seq_stop,
	.show   = seq_show,
};

static int seq_test_open(struct inode *inode, struct file *file)
{
	return seq_open(file, &seq_test_ops);
}

static const struct file_operations seq_test_fops = {
	.owner		= THIS_MODULE,
	.open		= seq_test_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= seq_release,
};

static int __init seq_test_init(void)
{
    int i, count;
    struct mylist_random *mylist_node;
    struct proc_dir_entry *p;

    p = proc_create("seq_file_test", S_IRUGO, NULL, &seq_test_fops);
    if (!p)
	goto out;

    for(i = 0; i < 10; i++) {
	mylist_node = kmalloc(sizeof(struct mylist_random), GFP_ATOMIC);
	if (!mylist_node)
	    return -ENOMEM;
	memset(mylist_node, 0, sizeof(struct mylist_random));
	get_random_bytes(&count, sizeof(int));
	sprintf(mylist_node->info, "random number %d: %d\n", i, count);
	printk("%s", mylist_node->info);
	list_add_tail(&mylist_node->list, &test_list);
    }
    
    return 0;
out:
    remove_proc_entry("seq_file_test", NULL);
    return -EFAULT;
}

static void __exit seq_test_exit(void)
{
    struct list_head *p, *q;
    struct mylist_random *mylist_node;

    list_for_each_safe(p, q, &test_list) {
	mylist_node = list_entry(p, struct mylist_random, list);
	list_del(p);
	kfree(mylist_node);
    }

    remove_proc_entry("seq_file_test", NULL);
}

module_init(seq_test_init);
module_exit(seq_test_exit);

MODULE_AUTHOR("Richard Tang <tanglinux@gmail.com>");
MODULE_LICENSE("GPL");

    (2)、编译、执行

//获得Ubuntu 11.04正在运行的内核版本
$ cat /proc/version
Linux version 2.6.38-13-generic (buildd@palmer) (gcc version 4.5.2 (Ubuntu/Linaro 4.5.2-8ubuntu4) ) #54-Ubuntu SMP Tue Jan 3 13:44:52 UTC 2012

//根据上面获得的信息,在Makefile中指定Ubuntu 11.04的内核源码目录为/usr/src/linux-headers-2.6.38-13-generic/
# Makefile
KERN_DIR = /usr/src/linux-headers-2.6.38-13-generic/

all:
	make -C $(KERN_DIR) M=`pwd` modules

clean:
	make -C $(KERN_DIR) M=`pwd` modules clean

obj-m += seq_file_test.o

//编译,并把编译好的模块seq_file_test.ko加载到内核中
$ make
$ sudo insmod seq_file_test.ko

//测试并比较采用以下两种不同方式输出的随机数
$ cat /proc/seq_file_test
random number 0: -1742888248
random number 1: 764069878
random number 2: -2023358059
random number 3: 663883285
random number 4: -1811369789
random number 5: -568958269
random number 6: 606443186
random number 7: -2108607843
random number 8: 762957660
random number 9: -2142996661

$ dmesg | tail -10
[ 2186.806122] random number 0: -1742888248
[ 2186.806436] random number 1: 764069878
[ 2186.806448] random number 2: -2023358059
[ 2186.806454] random number 3: 663883285
[ 2186.806464] random number 4: -1811369789
[ 2186.806470] random number 5: -568958269
[ 2186.806488] random number 6: 606443186
[ 2186.806493] random number 7: -2108607843
[ 2186.806503] random number 8: 762957660
[ 2186.806509] random number 9: -2142996661


评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tanglinux

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值