我试图创建自己的proc节点" os_pagemap"在Linux上(使用odroid)
该节点的目标是打印所有物理内存页面的信息。 (sudo cat / proc / os_pagemap)
像这样:
[PHY] Virt 483252 Phy 266908 VMA 0 PID 5773 PNAME com.sec.android.app.keyboard
[PHY] Virt 483253 Phy 266909 VMA 0 PID 5773 PNAME com.sec.android.app.keyboard
[PHY] Virt 483254 Phy 266910 VMA 0 PID 5773 PNAME com.sec.android.app.keyboard
[PHY] Virt 398391 Phy 266920 VMA /dev/ashmem/dalvik-bitmap-1 PID 5773 PNAME com.sec.android.app.keyboard
其中VMA是指VMA名称
为了实现目标,我的设计是这样的:
1. read_lock(&tasklock)
2. for_each_process(p) => get pids
3. read_unlock(&tasklock)
4. Loop for each pid
1)task = get_pid_task(pid)
2)if task==NULL => skip
3)mm=task->mm
4)down_read(&mm->mmap_sem)
5)Loop for each vma in mm
1>store vma information into os_pagemap_struct
6)up_read(&mm->mmap_sem)
5. Print os_pagemap_struct
但是,我无法找到解决方法 "获取vma信息"和"打印os_pagemap_struct"
这是我已经完成的代码: 我只得到" vm_start"和" vm_end"而我打印得不好。
struct os_pagemap{
unsigned long vm_start;
unsigned long vm_end;
//more on...
};
static ssize_t ospagemap_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
{
struct task_struct * p = NULL;
char * pagemap_buf = kmalloc(500, GFP_KERNEL);
int i = 0, j;
int cur = 0, bytes=0;
struct pid *pid_struct;
int pid[100];
struct mm_struct* mm;
struct os_pagemap pagemap;
struct vm_area_struct * vma;
int count = 0;
int buf_size = 0;
read_lock(&tasklist_lock);
for_each_process(p){ //get all process' pids
pid[i] = p->pid;
i++;
}
read_unlock(&tasklist_lock);
for (j = 0; j < i; j++){ //loop for each process
pid_struct = find_get_pid(pid[j]);
p = get_pid_task(pid_struct, PIDTYPE_PID);
put_pid(pid_struct);
if (p == NULL){ //skip this task
printk("[%d]p is NULL", pid[j]);
continue;
}
mm = p->mm;
if (mm == NULL){
printk("\n[%d]mm is NULL!\n",pid[j]);
continue;
}
down_read(&mm->mmap_sem);
vma = mm->mmap;
count = 0;
while (1){ //loop for each vma
if (vma == NULL){
printk("\n[%d]vma is NULL!\n", pid[j]);
break;
}
if (buf_size >= 450){
printk("Realloc size : %d\n", cur + 500);
krealloc(pagemap_buf, cur + 500, GFP_KERNEL);
buf_size = 0;
}
pagemap.vm_start = vma->vm_start;
pagemap.vm_end = vma->vm_end;
bytes = snprintf((cur > 0) ? cur + pagemap_buf : pagemap_buf,
500 - cur,
"Task : [%d]%s start : %lu end : %lu\n", p->pid, p->comm,
pagemap.vm_start, pagemap.vm_end);
printk("Task : [%d]%s start : %lu end : %lu\n", p->pid, p->comm,
pagemap.vm_start, pagemap.vm_end);
cur += bytes;
buf_size += bytes;
vma = vma->vm_next;
count++;
}
up_read(&mm->mmap_sem);
}
printk("cur : %d\n", cur);
copy_to_user(buf, pagemap_buf, (size<cur) ? size : cur);
return (size<cur) ? size : cur;
}
static int ospagemap_open(struct inode *inode, struct file *file)
{
printk("ospagemap opened");
return 0;
}
const struct file_operations proc_ospagemap_operations = {
.llseek = mem_lseek, /* borrow this */
.read = ospagemap_read,
.open = ospagemap_open,
};
static int __init proc_ospagemap_init(void)
{
proc_create("os_pagemap", 0, NULL, &proc_ospagemap_operations);
return 0;
}
fs_initcall(proc_ospagemap_init);