通过proc文件系统输出必要的Linux内核信息(中)
2014-02-15 10:11
471 查看
2、使用旧式proc接口的例子
本示例比较简单,先通过kmalloc函数分配一段TANGLINUX_LEN大小的内存,然后通过tanglinux_read和tanglinux_write函数来实现对这段内存的读写操作。
(1)、例子源代码
[cpp]
view plaincopyprint?
#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");
简要说明例子中主要函数的用法:
[cpp]
view plaincopyprint?
/* 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)、编译、加载和测试
[cpp]
view plaincopyprint?
//获得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!
本示例比较简单,先通过kmalloc函数分配一段TANGLINUX_LEN大小的内存,然后通过tanglinux_read和tanglinux_write函数来实现对这段内存的读写操作。
(1)、例子源代码
[cpp]
view plaincopyprint?
#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");
#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");
简要说明例子中主要函数的用法:
[cpp]
view plaincopyprint?
/* 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);
/* 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)、编译、加载和测试
[cpp]
view plaincopyprint?
//获得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!
相关文章推荐
- 通过proc文件系统输出必要的Linux内核信息(下)
- 通过proc文件系统输出必要的Linux内核信息(中)
- 通过proc文件系统输出必要的Linux内核信息(上)
- 通过proc文件系统输出必要的Linux内核信息(上)
- 通过proc文件系统输出必要的Linux内核信息(下)
- 通过proc文件系统让Linux内核空间和用户空间之间进行通信
- Linux内核-文件系统之/proc目录
- 基于/proc伪文件系统的读取系统常见内核状态信息
- 通过/proc文件系统找出系统瓶颈
- 通过读proc等方式获取Linux系统状态信息的一些方法
- IE下通过response输出流的方式,输出图片等文件信息到IE,图片显示不了,文件下载不了的问题。
- Linux文件系统调用----实现对树形文件结构的广度优先遍历,即按层输出文件信息
- proc文件系统创建实例二(引出 seq file 文件系统的创建过程,结构化信息显示)
- java.io 通过数据流、序列化和文件系统提供系统输入和输出
- Web系统通过EXE文件实现读取客户电脑MAC等硬件信息且兼容非IE浏览器
- 通过proc了解linux系统信息
- Linux内核中的Proc文件系统(一)
- 通过读proc方式获取Linux系统状态信息
- Linux内核学习之四--进程、进程调度、系统调用、proc文件系统和内核异常分析
- android-通过StatFs获取文件系统的空间信息