Linux Kernel HomeWork---/proc/mtest

Memory management

1.listvma

static void mtest_dump_vma_list(void)

{

struct task_struct *task =
current;               
//get the task_struct of the current process

struct mm_struct *mm = task->mm;

struct vm_area_struct
*vma;               
//get the vma area of the current process

int count = 0;     //the number of
vma

down_read(&mm->mmap_sem);

for(vma = mm->mmap; vma; vma = vma->vm_next)

{

count++;

printk("%d:  0x%lx 0x%lx ",
count, vma->vm_start, vma->vm_end);

if (vma->vm_flags &
VM_READ)

printk("r");

else

printk("-");

if (vma->vm_flags &
VM_WRITE)

printk("w");

else

printk("-");

if (vma->vm_flags &
VM_WRITE)

printk("x");

else

printk("-");

printk("\n");

}

up_read(&mm->mmap_sem);

}

2.findpage addr

static struct page *

my_follow_page(struct vm_area_struct *vma, unsigned long addr)

{

pgd_t *pgd;

pmd_t *pmd;

pud_t *pud;

pte_t *pte;

spinlock_t *ptl;

struct page *page = NULL;

struct mm_struct *mm = vma->vm_mm;

pgd = pgd_offset(mm, addr);     //get
pgd

if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd)))

goto out;

pud = pud_offset(pgd, addr);   //get pud

if (pud_none(*pud) || unlikely(pmd_bad(*pud)))

goto out;

pmd = pmd_offset(pud, addr);   //get pmd

if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd)))

goto out;

pte = pte_offset_map_lock(mm, pmd, addr, &ptl); //get
pte

if (!pte)

goto out;

if (!pte_present(*pte))   //pte not in
memory

goto unlock;

page = pfn_to_page(pte_pfn(*pte));

if (!page)

goto unlock;

get_page(page);

unlock:

pte_unmap_unlock(pte, ptl);

out:

return page;

}

static void mtest_find_page(unsigned long addr)

{

struct vm_area_struct *vma;

struct task_struct *task = current;

struct mm_struct *mm = task->mm;

unsigned long kernel_addr;

struct page *page;

down_read(&mm->mmap_sem);

vma = find_vma(mm, addr);

page = my_follow_page(vma, addr);

if (!page)

{

printk("translation
failed.\n");

goto out;

}

kernel_addr = (unsigned long) page_address(page);

kernel_addr += (addr & ~PAGE_MASK);

printk("vma 0x%lx -> pma 0x%lx\n", addr,
kernel_addr);

out:

up_read(&mm->mmap_sem);

}

3.writeval addr val

static void

mtest_write_val(unsigned long addr, unsigned long val)

{

struct vm_area_struct *vma;

struct task_struct *task = current;

struct mm_struct *mm = task->mm;

struct page *page;

unsigned long kernel_addr;

down_read(&mm->mmap_sem);

vma = find_vma(mm, addr);

//test if it is a legal vma

if (vma && addr >= vma->vm_start &&
(addr + sizeof(val)) < vma->vm_end)

{

if (!(vma->vm_flags &
VM_WRITE))   //test if we have rights to write

{

printk("cannot write to 0x%lx\n", addr);

goto
out;

}

page = my_follow_page(vma,
addr);

if (!page)

{

printk("page not found 0x%lx\n", addr);

goto
out;

}

kernel_addr = (unsigned long)
page_address(page);

kernel_addr += (addr &~
PAGE_MASK);

printk("write 0x%lx to address
0x%lx\n", val, kernel_addr);

*(unsigned long *)kernel_addr =
val;

put_page(page);

}

else

{

printk("no vma found for %lx\n",
addr);

}

out:

up_read(&mm->mmap_sem);

}

4.To build a proc file

static ssize_t

mtest_write(struct file *file, const char __user *buffer, size_t count,
loff_t *data)

{

char buf[128];

unsigned long val, val2;

if (count > sizeof(buf))

return -EINVAL;

if (copy_from_user(buf, buffer, count))   
//get the command from shell

return -EINVAL;

if (memcmp(buf, "listvma", 7) == 0)

mtest_dump_vma_list();

else if (memcmp(buf, "findpage", 8) == 0)

{

if (sscanf(buf+8, "%lx", &val)
== 1)

mtest_find_page(val);

}

else if (memcmp(buf, "writeval", 8) == 0)

{

if (sscanf(buf+8, "%lx %lx",
&val, &val2) == 2)

{

mtest_write_val(val, val2);

}

}

return count;

}

static struct

file_operations proc_mtest_operation = {

write: mtest_write,

};

static int __init

mtest_init(void)

{

proc_create("mtest", 0, NULL,
&proc_mtest_operation);

printk("Create mtest...\n");

return 0;

}

static void __exit

mtest_exit(void)

{

remove_proc_entry("mtest", NULL);

}

MODULE_LICENSE("GPL");

MODULE_DESCRIPTION("memory management task");

module_init(mtest_init);

module_exit(mtest_exit);

6.some head files that should be included

#include <linux/module.h>

#include <linux/kernel.h>

#include <linux/proc_fs.h>

#include <linux/string.h>

#include <linux/vmalloc.h>

#include <linux/init.h>

#include <linux/slab.h>

#include <linux/fs.h>

#include <linux/mm.h>

#include <linux/sched.h>

#include <linux/errno.h>

7. how to test

1) write a Makefile

2) type “make” in shell

3) type ”sudo insmod mtest.ko”

4) type “sudo -su”

5) type:   echo “listvma” > /proc/mtest

6) type: dmesg (then you will find a lot of vma)

7) choose one of them and type : echo “findpage 0x.........” >
/proc/mtest

then type : dmesg

note: you may find that “translation failed” shows up. But that
does not mean you fail the        test. Please
choose an address between the start and the end of the vma listed.

e.g.
0x123 – 0x345

you
may want to type: echo “findpage 0x300” > /proc/mtest

because you cannot be sure if the beginning of the virtual address is used.

8) choose an address that you has rights to write.

Then type: echo  “writeval
0x...    123” > /proc/mtest

type: dmesg

note: 123 can be any unsigned int

you‘d better choose the same address to test in both step 7 and 8, so that you
will see

if the
physical address is consistent.

The End.

Linux Kernel HomeWork---/proc/mtest,布布扣,bubuko.com

时间: 2024-10-13 23:27:34

Linux Kernel HomeWork---/proc/mtest的相关文章

linux kernel (proc文件系统)参数

http://blog.csdn.net/guowake/article/details/3279796 Linux Proc文件系统,通过对Proc文件系统进行调整,达到性能优化的目的. 二./proc/sys/kernel/优化1)     /proc/sys/kernel/ctrl-alt-del该文件有一个二进制值,该值控制系统在接收到ctrl+alt+delete按键组合时如何反应.这两个值分别是:零(0)值,表示捕获ctrl+alt+delete,并将其送至 init 程序:这将允许

Linux Kernel - Debug Guide (Linux内核调试指南 )

http://blog.csdn.net/blizmax6/article/details/6747601 linux内核调试指南 一些前言 作者前言 知识从哪里来 为什么撰写本文档 为什么需要汇编级调试 ***第一部分:基础知识*** 总纲:内核世界的陷阱 源码阅读的陷阱 代码调试的陷阱 原理理解的陷阱 建立调试环境 发行版的选择和安装 安装交叉编译工具 bin工具集的使用 qemu的使用 initrd.img的原理与制作 x86虚拟调试环境的建立 arm虚拟调试环境的建立 arm开发板调试环

ubuntu/linux mint 创建proc文件的三种方法(二)

在做内核驱动开发的时候,可以使用/proc下的文件,获取相应的信息,以便调试. 大多数/proc下的文件是只读的,但为了示例的完整性,都提供了写方法. 方法一:使用create_proc_entry创建proc文件(简单,但写操作有缓冲区溢出的危险): 方法二:使用proc_create和seq_file创建proc文件(较方法三简洁): 方法三:使用proc_create_data和seq_file创建proc文件(较麻烦,但比较完整): 示例四:在proc文件中使用内核链表的一个示例(用的方

ubuntu/linux mint 创建proc文件的三种方法(四)

在做内核驱动开发的时候,可以使用/proc下的文件,获取相应的信息,以便调试. 大多数/proc下的文件是只读的,但为了示例的完整性,都提供了写方法. 方法一:使用create_proc_entry创建proc文件(简单,但写操作有缓冲区溢出的危险): 方法二:使用proc_create和seq_file创建proc文件(较方法三简洁): 方法三:使用proc_create_data和seq_file创建proc文件(较麻烦,但比较完整): 示例四:在proc文件中使用内核链表的一个示例(用的方

Linux: the schedule algorithm in Linux kernel

Linux kernel里面用到的一个叫 CFS (Completely-Fair-Scheduler)的调度算法.在网上找的描述都很不直观,很难读.但是找到了一篇很通俗易懂的(大道至简啊...): http://people.redhat.com/mingo/cfs-scheduler/sched-design-CFS.txt 为了防止链接失效,粘贴全文如下: This is the CFS scheduler. 80% of CFS's design can be summed up in

2. ubuntu下载编译linux kernel

一. 引言 诚如老罗所言,android源代码里面并没有带linux kernel代码.它使用的是预先编译好的kernel,大家可以使用adb shell cat proc/version就可以查看到,如下: [email protected]:~/working_directory$ adb shell cat proc/version Linux version 2.6.29-00261-g0097074-dirty ([email protected]) (gcc version 4.4.

Linux Kernel学习笔记

转自:http://blog.sina.com.cn/s/blog_55465b470100eb8c.html 这里贴部分内容: Chapter 2. 设备驱动程序开发 在编程思路上,机制表示需要提供什么功能,策略表示如何使用这些功能.区分机制和策略是UNIX设计最重要和最好的思想之一.如X系统就由X服务器和X客户端组成.X服务器实现机制,负责操作硬件,给用户程序提供一个统一的接口.而X客户端实现策略,负责如何使用X服务器提供的功能.设备驱动程序也是机制与策略分离的典型应用.在编写硬件驱动程序时

CentOS启动流程、Grub legacy配置、linux kernel模块管理、伪文件系统介绍

写在前面: 博客书写牢记5W1H法则:What,Why,When,Where,Who,How. 本篇主要内容: ● 启动相关基础概念汇总 ● 启动流程 ● init程序类型     /etc/rc.d/rc     chkconfig     /etc/rc.d/rc.sysinit ● GRUB legacy     命令行接口     配置文件 ● Linux Kernel     内核模块查看与管理         lsmod         modinfo         modprob

ubuntu/linux mint 创建proc文件的三种方法(一)

在做内核驱动开发的时候,可以使用/proc下的文件,获取相应的信息,以便调试. 大多数/proc下的文件是只读的,但为了示例的完整性,都提供了写方法. 方法一:使用create_proc_entry创建proc文件(简单,但写操作有缓冲区溢出的危险): 方法二:使用proc_create和seq_file创建proc文件(较方法三简洁): 方法三:使用proc_create_data和seq_file创建proc文件(较麻烦,但比较完整): 示例四:在proc文件中使用内核链表的一个示例(用的方