kernel struct file结构中的private_data



转自:http://blog.csdn.net/bush2582/article/details/7731220

struct file是字符设备驱动相关重要结构。struct file代表一个打开的文件描述符,它不是专门给驱动程序使用的,系统中每一个打开的文件在内核中都有一个关联的 struct file。 它由内核在 open时创建,并传递给在文件上操
作的任何函数,知道最后关闭。当文件的所有实例都关闭之后,内核释放这个数据结构。
   在 struct filed有个成员void *private_data;文档上说明该成员是系统调用时保存状态信息非常有用的资源。起初一直不明白这个private_data在驱动 open函数中的作用,后来发现private_data 这个成员在open函数被调用的时候 linux 系统就已经将其幅值为NULL,之后可供用户使用,或者比较悲剧的被用户忽略改域。
   在详细的阅读源代码后,发现 这个private_data 其实是用来保存自定义设备结构体的地址的。自定义结构体的地址被保存在private_data后,可以在read ,write 等驱动函数中被传递和调用自定义设备结构体中的成员。
   例如 可以在open函数中这么做
struct scull_dev *dev;

dev = container_of(inode->i_cdev,struct scull_dev,cdev);

filp->private_data = dev; /*for other methods*/
(container_of这个宏返回的是地址,即结构体的地址)
  也可以使用C语言中的一些技巧实现地址的赋值

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
#include <linux/init.h> /* __init and __exit macroses */ #include <linux/kernel.h> /* KERN_INFO macros */ #include <linux/module.h> /* required for all kernel modules */ #include <linux/moduleparam.h> /* module_param() and MODULE_PARM_DESC() */ #include <linux/fs.h> /* struct file_operations, struct file */ #include <linux/miscdevice.h> /* struct miscdevice and misc_[de]register() */ #include <linux/slab.h> /* kzalloc() function */ #include <linux/uaccess.h> /* copy_{to,from}_user() */ #include <linux/init_task.h> //init_task再次定义 #include "proc_relate.h" MODULE_LICENSE("GPL"); MODULE_AUTHOR("Wu Yimin>"); MODULE_DESCRIPTION("proc_relate kernel modoule"); static int proc_relate_open(struct inode *inode, struct file *file) { struct proc_info *buf; int err = 0; buf=kmalloc(sizeof(struct proc_info)*30,GFP_KERNEL); file->private_data = buf; return err; } static ssize_t proc_relate_read(struct file *file, char __user * out,size_t size, loff_t * off) { struct proc_info *buf = file->private_data; /* 你需要补充的代码 */ } static int proc_relate_close(struct inode *inode, struct file *file) { struct buffer *buf = file->private_data; kfree(buf); return 0; } static struct file_operations proc_relate_fops = { .owner = THIS_MODULE, .open = proc_relate_open, .read = proc_relate_read, .release = proc_relate_close, .llseek = noop_llseek }; static struct miscdevice proc_relate_misc_device = { .minor = MISC_DYNAMIC_MINOR, .name = "proc_relate", .fops = &proc_relate_fops }; static int __init proc_relate_init(void) { misc_register(&proc_relate_misc_device); printk(KERN_INFO "proc_relate device has been registered.\n"); return 0; } static void __exit proc_relate_exit(void) { misc_deregister(&proc_relate_misc_device); printk(KERN_INFO "proc_relate device has been unregistered\n"); } module_init(proc_relate_init); module_exit(proc_relate_exit);补充这段代码需要补充的函数部分,使其能编译为内核模块,安装该内核模块后测试程序,运行结果类似如下:Here is parent process,pid = 7329 this is a child,pid is 7330 this is another child,pid is 7331 this is a child,pid is 7333 In thread,pid=7331 tid=7334 thread id=1254224352 this is a child,pid is 7332 this is a child,pid is 7335 ------------------------------------------------------- pid=2616 tgid=2616 comm=sshd sessionid=4 mm=ffff8000fae19000 activeMM=ffff8000fae19000 parent =1971 real_parent=1971 group_leader2616 ------------------------------------------------------- pid=2670 tgid=2670 comm=sshd sessionid=4 mm=ffff8000fa477500 activeMM=ffff8000fa477500 parent =2616 real_parent=2616 group_leader2670 -------------------------------------------------------
05-17
这段代码缺少的部分是 proc_relate_read() 函数的实现。这个函数需要完成从内核空间读取信息并将其复制到用户空间的功能。 以下是一个可能的实现: static ssize_t proc_relate_read(struct file *file, char __user * out, size_t size, loff_t * off) { struct proc_info *buf = file->private_data; struct task_struct *task; int count = 0; char *tmp_buf; if (*off > 0) { return 0; /* End of file */ } tmp_buf = kmalloc(size, GFP_KERNEL); if (!tmp_buf) { return -ENOMEM; } /* Traverse the process tree and copy information to buffer */ for_each_process(task) { snprintf(tmp_buf + count, size - count, "this is a child,pid is %d\n", task->pid); count += strlen(tmp_buf + count); if (list_empty(&task->children)) { continue; } /* Traverse the children of the current task */ list_for_each_entry(task, &task->children, sibling) { snprintf(tmp_buf + count, size - count, "this is a child,pid is %d\n", task->pid); count += strlen(tmp_buf + count); } } /* Copy buffer to user space */ if (copy_to_user(out, tmp_buf, count)) { kfree(tmp_buf); return -EFAULT; } *off += count; kfree(tmp_buf); return count; } 这个函数使用了 for_each_process() 宏来遍历进程树,并将每个进程的 PID 写入缓冲区。然后,它使用 copy_to_user() 函数将缓冲区的内容复制到用户空间。 注意,该实现并不完美。例如,它没有处理缓冲区溢出的情况,并且只返回进程的 PID,而不是更有用的信息。但是,它可以作为一个起点,让你了解如何在内核模块读取和复制信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值