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

     2、使用旧式proc接口的例子

    本示例比较简单,先通过kmalloc函数分配一段TANGLINUX_LEN大小的内存,然后通过tanglinux_read和tanglinux_write函数来实现对这段内存的读写操作。

    (1)、例子源代码 

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/uaccess.h>
#include <linux/proc_fs.h>
#include <linux/slab.h>
#include <linux/string.h>

#define TANGLINUX_LEN 10

static char *buf;

static int proc_output(char *page)
{
	char *p = page;

	p += sprintf(p, "%s", buf);

	return p - page;
}

static int tanglinux_read(char *page, char **start, off_t off,
			  int count, int *eof, void *data)
{
	int len;

	len = proc_output(page);
	if (len <= off + count)
		*eof = 1;
	*start = page + off;
	len -= off;
	if (len > count)
		len = count;
	if (len < 0)
		len = 0;
	
	return len;
}

static int tanglinux_write(struct file *file, const char __user *buffer,
			   unsigned long count, void *data)
{
	int ret;

	if (count > TANGLINUX_LEN) {
		printk("proc_test: buf is full!\n");
		return -ENOSPC;
	}

	ret = copy_from_user(buf, buffer, count);
	if (ret)
		return -EFAULT;
	
	return count;
}

static int __init tanglinux_init(void)
{
	static struct proc_dir_entry *entry = NULL ;

	buf = kmalloc(TANGLINUX_LEN, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;
	memset(buf, 0, TANGLINUX_LEN);
		
	entry = create_proc_entry("proc_test", S_IWUGO, NULL);
	if (!entry)
	{
		printk("proc_test: Couldn't create proc entry\n");
		
		return -EFAULT;
	}
	entry->read_proc  = tanglinux_read;
	entry->write_proc = tanglinux_write;

	return 0;
}

static void __exit tanglinux_exit(void)
{
	remove_proc_entry("proc_test", NULL);
	kfree(buf);
}

module_init(tanglinux_init);
module_exit(tanglinux_exit);

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

    简要说明例子中主要函数的用法: 

/* linux-2.6.38.8/include/linux/proc_fs.h */
extern struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode,
						struct proc_dir_entry *parent);
extern void remove_proc_entry(const char *name, struct proc_dir_entry *parent);

    create_proc_entry函数用于在parent(当parent为NULL时即为在/proc目录下)目录下创建名为name的proc条目,参数mode用于设置此条目的访问权限以及文件类型(例子中设置proc_test的访问权限为所有用户可写,但只有拥有超级用户权限时才可以读)。

    remove_proc_entry函数用于删除parent(当parent为NULL时即为在/proc目录下)目录下名为name的proc条目。

    (2)、编译、加载和测试 

//获得Ubuntu 11.04正在运行的内核版本
$ cat /proc/version
Linux version 2.6.38-13-generic (buildd@roseapple) (gcc version 4.5.2 (Ubuntu/Linaro 4.5.2-8ubuntu4) ) #53-Ubuntu SMP Mon Nov 28 19:23:39 UTC 2011

//根据上面获得的信息,在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 += tanglinux.o

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

//测试
$ sudo cat /proc/proc_test
$ echo "hello" > /proc/proc_test
$ sudo cat /proc/proc_test
hello
$ echo "hello world" > /proc/proc_test //输入超过10个字符的字符串时会出错
bash: echo: write error: No space left on device
//通过dmesg命令可以查看到例子中printk函数打印的错误信息
$ dmesg | tail -1
[  427.791649] proc_test: buf is full!

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

tanglinux

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

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

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

打赏作者

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

抵扣说明:

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

余额充值