不吃苦中苦,难为人上人。努力,给老婆孩子提供个良好的生活居住环境。

http://www.cnblogs.com/nan-jing/articles/5806399.html

上文提到。可以自动创建了设备节点。这次我们研究下。如何创建/proc文件系统下的节点呢? 有如何实现/proc节点的读写呢?

老规矩,为了方便大家复制粘贴。我直接贴全部源码,复制下来,可以直接编译运行的。

#include<linux/module.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <asm/io.h>
//#include <asm/system.h>
#include <asm/uaccess.h>
#include <linux/slab.h>
#include <linux/device.h>
#include <linux/proc_fs.h>

MODULE_AUTHOR("qcom.shanghai@gmail.com");
MODULE_LICENSE("Dual BSD/GPL");

#define GLOBALMEM_SIZE 0X1000
#define MEM_CLEAR 0x1

#define CJ_PROC_ENTRY "cjzang"
#define CJ_PROC_NODE "cj_entry"

static int globalmem_major = 0;

struct globalmem_dev{
struct cdev cdev;
unsigned char mem[GLOBALMEM_SIZE];
};

struct globalmem_dev *globalmem_devp;

struct class *globalmem_class;

struct proc_dir_entry *proc_cj_entry;

static int globalmem_open(struct inode *inode, struct file *filp){
struct globalmem_dev *dev;
dev = container_of(inode->i_cdev, struct globalmem_dev, cdev);
filp->private_data = dev; //臧春杰 marvell
printk(KERN_ALERT "globalmem_open!");
return 0;
}

static int globalmem_release(struct inode *inode, struct file *filp){
printk(KERN_ALERT "globalmem_release!");
return 0;
}

static ssize_t globalmem_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos){
unsigned long p = *ppos;
unsigned int count = size;
int ret = 0;
struct globalmem_dev *dev = filp->private_data;
//臧春杰 honeywell
if (p >= GLOBALMEM_SIZE){
return 0;
}
if (count > GLOBALMEM_SIZE - p){
count = GLOBALMEM_SIZE - p;
}

if (copy_to_user(buf, (void *)(dev->mem + p), count)){
ret = - EFAULT;
}else {
*ppos += count;
ret = count;
printk(KERN_ALERT "read %u bytes from %lu \n", count, p);
}
return ret;
}

static ssize_t globalmem_write(struct file *filp, const char __user *buf, size_t size, loff_t *ppos){
unsigned long p = *ppos;
unsigned int count = size;

int ret = 0;
struct globalmem_dev *dev = filp->private_data;

if (p >= GLOBALMEM_SIZE){
return 0;
}

if (count > GLOBALMEM_SIZE - p){
count = GLOBALMEM_SIZE - p;
}
if (copy_from_user(dev->mem + p, buf, count)){
ret = - EFAULT;
}else {
*ppos += count;
ret = count;
printk(KERN_ALERT "write %u bytes from %lu \n", count, p);
}

return ret;
}

static loff_t globalmem_llseek(struct file *filp, loff_t offset, int orig){
loff_t ret = 0;
switch(orig){
case 0:
if (offset < 0){
ret = - EFAULT;
break;
}
if ((unsigned int)offset > GLOBALMEM_SIZE){
ret = - EFAULT;
break;
}
filp->f_pos = (unsigned int) offset;
ret = filp->f_pos;
break;

case 1:
if ((filp->f_pos + offset) > GLOBALMEM_SIZE){
ret = - EFAULT;
break;
}

if ((filp->f_pos + offset) < 0){
ret = - EFAULT;
break;
}
filp->f_pos += offset;
ret = filp->f_pos;
break;

default:
ret = - EFAULT;
break;
}

return ret;

}

static long globalmem_ioctl(struct file *flip, unsigned int cmd, unsigned long arg){
printk(KERN_ALERT "globalmem_ioctl");
return 10L;
}

static const struct file_operations globalmem_fops = {
.owner = THIS_MODULE,
.llseek = globalmem_llseek,
.read = globalmem_read,
.write = globalmem_write,
.unlocked_ioctl = globalmem_ioctl,
.open = globalmem_open,
.release = globalmem_release,
};

static int proc_show(struct seq_file *file, void *v){
printk(KERN_ALERT "proc driver show!!!");
seq_printf(file, "proc driver: %s\n", "proc_proc_test");
return 0;
}

static int proc_open(struct inode *inode, struct file *file){
printk(KERN_ALERT "proc driver open!!!");
single_open(file, proc_show, NULL);
return 0;
}

static ssize_t proc_cj_write(struct file *file, const char __user *buffer, size_t count, loff_t *pos){
printk(KERN_ALERT "proc driver wirte!!!");
return 100;
}

static struct file_operations proc_file_ops = {
.owner = THIS_MODULE,
.open = proc_open,
.read = seq_read,
//臧春杰 honeywell
.write = proc_cj_write,
.release = single_release,
};

static void globalmem_setup_cdev(struct globalmem_dev *dev, int index /*臧春杰 honeywell*/){
int err, devno = MKDEV(globalmem_major, index);
cdev_init(&(dev->cdev), &globalmem_fops);
dev->cdev.owner = THIS_MODULE;
err = cdev_add(&dev->cdev, devno, 1);
if (err){
printk(KERN_ALERT"cdev_add failed!");
}
}
static int cj_proc_read(char *page, char **start, off_t off, int count, int *eof, void *data){
return 100;
}

static int cj_proc_write(struct file *file, const char *buffer, unsigned long count, void *data){
//臧春杰 honeywell
return 100;
}

static int create_cj_entry(void){
proc_cj_entry = proc_mkdir(CJ_PROC_ENTRY, NULL);
if (proc_cj_entry == NULL){
printk(KERN_ALERT"create /proc/%s failed \n", CJ_PROC_ENTRY);
return -1;
}

printk(KERN_ALERT"create /proc/%s success \n", CJ_PROC_ENTRY);
struct proc_dir_entry *pt_entry = proc_create(CJ_PROC_NODE, 0666, proc_cj_entry, &proc_file_ops);
if (pt_entry == NULL){
//臧春杰 honeywell
return -1;
}
// pt_entry->read_proc = cj_proc_read;
// pt_entry->write_proc = cj_proc_write;

return 0;
}

static void create_dev_node(int index){
device_create(globalmem_class, NULL, MKDEV(globalmem_major, index), NULL, "globalmem_cj1");
device_create(globalmem_class, NULL, MKDEV(globalmem_major, index + 1), NULL, "globalmem_cj2");
}

static int __init globalmem_init(void){
int result;
dev_t devno = MKDEV(globalmem_major, 0);
if (globalmem_major){
result = register_chrdev_region(devno, 2, "globalmem");
}else {
result = alloc_chrdev_region(&devno,0, 2, "globalmem");
globalmem_major = MAJOR(devno);
}
printk(KERN_ALERT "major-------------->%d \n", globalmem_major);
if (result < 0){
return result;
}

globalmem_class = class_create(THIS_MODULE, "globalmem_cls");
create_dev_node(0);

globalmem_devp = kmalloc(2 * sizeof(struct globalmem_dev), GFP_KERNEL);
if (! globalmem_devp){
result = -ENOMEM;
goto fail_malloc;
}
memset(globalmem_devp, 0, 2 * sizeof(struct globalmem_dev));
globalmem_setup_cdev(&globalmem_devp[0], 0);
globalmem_setup_cdev(&globalmem_devp[1], 1);

create_cj_entry();
return 0;

fail_malloc:
unregister_chrdev_region(devno, 1);
return result;
}

static void __exit globalmem_exit(void){
cdev_del(&globalmem_devp[0].cdev);

cdev_del(&globalmem_devp[1].cdev);
kfree(globalmem_devp);
unregister_chrdev_region(MKDEV(globalmem_major, 0), 2);
class_destroy(globalmem_class);
remove_proc_entry(CJ_PROC_ENTRY, NULL);
remove_proc_entry(CJ_PROC_NODE, proc_cj_entry);
}

module_param(globalmem_major, int, S_IRUGO);
module_init(globalmem_init);
module_exit(globalmem_exit);

我们可以看到。主要用到了proc_mkdir proc_create函数,读实现原理是

在打开节点时候,把proc_show传进去。保存起来,以备读。当上层应用需要读的时候,进入seq_read函数,该函数又会叫到我们穿进去的参数proc_show。

一点点入门,一点点学习,关键在于坚持。要不断积累。感谢marvell, 感谢honeywell

忘了要注意。 我的版本是ubuntu1604, 我在创建proc节点的时候,用了网上说的create_proc_entry方法创建,不行的。 好像这个方便过时了。不建议使用了。这个要注意。

最新文章

  1. Windows桌面共享中一些常见的抓屏技术
  2. Oracle数据库,查询语句、内置函数
  3. sublime text之sublimeCodeIntel 的配置
  4. [游戏学习29] Win32 图像处理1
  5. Go Go
  6. 4G时代的抢钱之道
  7. 将json转为复杂url参数
  8. Reading or Writing to Another Processes Memory in C# z
  9. Slickflow.NET 开源工作流引擎基础介绍(六)--模块化架构设计和实践
  10. Windows系统性能提升方法
  11. ExtJs MVC应用架构示例
  12. 容器 list
  13. iOS平台下cookie的使用
  14. cf C. Alice and Bob
  15. 【RequireJS--API学习笔记】
  16. ubuntu 操作系统相关操作
  17. peoplesoft function PSTREENODE 通过 deptid 获得部门树 全路径 名称
  18. 用html和css轻松实现康奈尔笔记(5R笔记)模板
  19. 用python实现单向链表
  20. (转)Spring boot(一):入门篇

热门文章

  1. Hibernate 系列教程10-组成关系
  2. Setting DPDK+OVS+QEMU on CentOS
  3. Loadrunner之脚本的调试和保存(六)
  4. [转]Android 导入v7包常见错误,以及项目引用v7包错误解决
  5. JVM垃圾收集算法——分代收集算法
  6. Ubuntu下安装使用MongoDB
  7. ubuntu虚拟机和主机互ping及secureCRT使用
  8. android性能优化优秀文章
  9. zf-关于SYS_User表type的分类
  10. 【树状数组】 poj 2352