warriorpaw 发表于 2013-07-17 17:07

如何在内核态读取任意进程的虚拟地址上的数据》?

RT
在写驱动的时候用copy_from_user可以访问current对应进程的虚拟地址上的数据

但是,如果我需要访问另外一个进程,而不是这次调用驱动的那个进程的虚拟地址,该怎么办??
知道PID和对应的struct task_struct结构

各位高手支下招吧,小弟跪谢了

xifanlover 发表于 2013-07-18 11:22

不知道建立共享内存可不可以实现你的目的。

wwxxxxll 发表于 2013-07-20 10:09

你的问题,我先确认一下,copy_from_user是访问用户地址空间,不是current对应进程的虚拟地址上的数据。

如果我需要访问另外一个进程,而不是这次调用驱动的那个进程的虚拟地址,该怎么办??
知道PID和对应的struct task_struct结构

我可不可以理解为知道进程的struct task_struck获取进程的虚拟地址!
我就回答这个问题,首先每个进程看到得虚拟地址空间有大量准确定义的区(area)构成,每个区都有专门的功能。代码段、数据段、堆栈段等。
在struct task_struct中有一个struct mm_struct *mm,该结构体记录了进程内存使用的相关情况。
列出部分
//linux-3.2.36

struct mm_struct {
      struct vm_area_struct * mmap;         /* list of VMAs */
//一个进程的虚拟空间中可能有多个虚拟区间(参见下面对vm_area_struct描述),对这些虚拟区间的组织方式有两种,当虚拟区较少时采用单链表,由mmap指针指向这个链表.
      struct rb_root mm_rb;
//当虚拟区间多时采用“红黑树(red_black tree)”结构,由mm_rb指向这颗树。
      struct vm_area_struct * mmap_cache;   /* last find_vma result */
//因为程序中用到的地址常常具有局部性,因此,最近一次用到的虚拟区间很可能下一次还要用到,因此,把最近用到的虚拟区间结构应当放入高速缓存,这个虚拟区间就由mmap_cache指向。
...
      unsigned long mmap_base;                /* base of mmap area */
      unsigned long task_size;                /* size of task vm space */
      unsigned long cached_hole_size;         /* if non-zero, the largest hole below free_area_cache */
      unsigned long free_area_cache;          /* first hole of size cached_hole_size or larger */
      pgd_t * pgd;
//pgd指向该进程的页目录(每个进程都有自己的页目录,注意同内核页目录的区别),当调度程序调度一个程序运行时,就将这个地址转成物理地址。
      atomic_t mm_users;                      /* How many users with user space? */
      atomic_t mm_count;                      /* How many references to "struct mm_struct" (users count as 1) */
      int map_count;                        /* number of VMAs */
...
      struct rw_semaphore mmap_sem;
//如果你要访问此进程的虚拟区间,你可能要上锁,但这不是个好方法,你可能会影响此进程的运行;如果你不上锁,读取的数据可能有问题。
...
      unsigned long start_code, end_code, start_data, end_data;
      unsigned long start_brk, brk, start_stack;
      unsigned long arg_start, arg_end, env_start, env_end;
//描述了代码段、数据段、堆栈段、参数段以及环境段的起始地址和结束地址。
...

struct vm_area_struct部分代码

struct vm_area_struct {
      struct mm_struct * vm_mm;       /* The address space we belong to. */
      unsigned long vm_start;         /* Our start address within vm_mm. */
      unsigned long vm_end;         /* The first byte after our end address
                                           within vm_mm. */

      /* linked list of VM areas per task, sorted by address */
      struct vm_area_struct *vm_next, *vm_prev;

      pgprot_t vm_page_prot;          /* Access permissions of this VMA. */
      unsigned long vm_flags;         /* Flags, see mm.h. */
...
上面这个不用怎么解释吧
...      
      /* Function pointers to deal with this struct. */
      const struct vm_operations_struct *vm_ops;
...
deal with this struct
所以要用vm_ops访问vm_area_struct//在mm.h中,自己看吧

红黑树
定义在./include/rbtree.h中,自己看如何访问

struct rb_node
{
      unsigned longrb_parent_color;
#define RB_RED          0
#define RB_BLACK      1
      struct rb_node *rb_right;
      struct rb_node *rb_left;
} __attribute__((aligned(sizeof(long))));
    /* The alignment might seem pointless, but allegedly CRIS needs it */

struct rb_root
{
      struct rb_node *rb_node;
};
我感觉这不是你要的答案。但从你的题目上看是这样。
页: [1]
查看完整版本: 如何在内核态读取任意进程的虚拟地址上的数据》?