Chinaunix首页 | 论坛 | 博客
  • 博客访问: 693385
  • 博文数量: 192
  • 博客积分: 1875
  • 博客等级: 上尉
  • 技术积分: 2177
  • 用 户 组: 普通用户
  • 注册时间: 2010-10-23 23:21
个人简介

有时候,就是想窥视一下不知道的东东,因为好奇!

文章分类

全部博文(192)

文章存档

2024年(8)

2023年(3)

2020年(1)

2019年(1)

2018年(1)

2017年(2)

2016年(69)

2015年(53)

2014年(14)

2013年(1)

2012年(5)

2011年(25)

2010年(9)

分类: LINUX

2011-04-20 23:58:29

看看s3c2440上linux用户地址空间。
将当前命令的地址信息从/proc/procfile文件中读出
使用2.6.36内核

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/proc_fs.h>
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/vmalloc.h>
#include <asm/uaccess.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("zhanglong");
#define MAX_COOKIE_LENGTH PAGE_SIZE

static struct proc_dir_entry *proc_entry;
static char *cookie_pot; // Space for procfile strings

ssize_t proc_write(struct file *filp, const char __user *buff,
        unsigned long len, void *data)
{
   return 1; //如果返回0, 写数据时不能返回
}

int proc_read(char *page, char **start, off_t off,
        int count, int *eof, void *data)
{
    int len = 0;
    unsigned long ttb = 0;
    struct vm_area_struct *vm = current->mm->mmap;

    memset(page, 0, MAX_COOKIE_LENGTH);
//从c2读ttb
    __asm__ __volatile__ (
            "mrc p15, 0, %0, c2, c0, 0\n"
            :"=r" (ttb)
   );
           
    sprintf(page + len, "**********get the address information**********\n");
    len = strlen(page);
    sprintf(page + len, "current->comm: %s\n", current->comm); //执行当前进程的命令的名字
    len = strlen(page);
    sprintf(page + len, "current->state: %d\n", current->state); //运行状态
    len = strlen(page);
    sprintf(page + len, "currentr->mm = 0x%08x\n", current->mm);
    len = strlen(page);
    sprintf(page + len, "ttb = 0x%08x\n", ttb);
    len = strlen(page);
    sprintf(page + len, "currentr->mm->pgd = 0x%08x\n", current->mm->pgd); //页目录表的地址(好象与ttb相差0x90000000)
    len = strlen(page);
    sprintf(page + len, "**********the virtual memory area***************\n");
    len = strlen(page);
    sprintf(page + len, "vm_area: 0x%08x - 0x%08x\n", current->mm->mmap->vm_start, current->mm->mmap->vm_end); //
    len = strlen(page);

    vm = vm->vm_next;
    while((NULL != vm) && (vm != current->mm->mmap)){
        sprintf(page + len, "vm_area: 0x%08x - 0x%08x\n", vm->vm_start, vm->vm_end); //
        len = strlen(page);
        vm = vm->vm_next;
    };

    sprintf(page + len, "total_vm: 0x%x\t locked_vm: 0x%x\t shared_vm: 0x%x\t exec_vm: 0x%x\n",
            current->mm->total_vm, //进程地址空间的大小(页)
            current->mm->locked_vm, //锁住不能换出的页的个数
            current->mm->shared_vm, //共亨文件内存映射的页数
            current->mm->exec_vm); //可执行内存映射中的页数
    len = strlen(page);
    sprintf(page + len, "code: 0x%08x - 0x%08x\n",
            current->mm->start_code,
            current->mm->end_code); //代码

    len = strlen(page);
    sprintf(page + len, "data: 0x%08x - 0x%08x\n",
            current->mm->start_data,
            current->mm->end_data); //数据

    len = strlen(page);
    sprintf(page + len, "brk: 0x%08x - 0x%08x\n",
            current->mm->start_brk,
            current->mm->brk); //堆

    len = strlen(page);
    sprintf(page + len, "start_stack: 0x%08x\n", current->mm->start_stack); //用户堆栈的起始地址

    len = strlen(page);
    sprintf(page + len, "stack_vm: %d\n", current->mm->stack_vm); //用户态堆栈中的页数

    len = strlen(page);
    sprintf(page + len, "arg_area: 0x%08x - 0x%08x\n", current->mm->arg_start, current->mm->arg_end); //命令行参数的起始地址

    len = strlen(page);
    sprintf(page + len, "env_area: 0x%08x - 0x%08x\n", current->mm->env_start, current->mm->env_end); //环境变量的起始地址
    len = strlen(page);
    sprintf(page + len, "len = %d\n", len); //
    len = strlen(page);

    return len;
}

int init_proc_module(void)
{
    int ret = 0;
    cookie_pot = (char *)vmalloc(MAX_COOKIE_LENGTH);
    if (!cookie_pot)
    {
        ret = -ENOMEM;
    }
    else
    {
        memset(cookie_pot, 0, MAX_COOKIE_LENGTH);
        proc_entry = create_proc_entry("procfile", 0644, NULL);
        if (proc_entry == NULL)
        {
            ret = -ENOMEM;
            vfree(cookie_pot);
            printk(KERN_INFO "proc: Couldn't create proc entry\n");
        }
        else
        {
            proc_entry->read_proc = proc_read;
            proc_entry->write_proc = proc_write;
            //proc_entry->owner = THIS_MODULE;

            printk(KERN_INFO "proc: Module loaded.\n");
        }
    }
    return ret;
}
void cleanup_proc_module(void)
{
    remove_proc_entry("proc", NULL);
    vfree(cookie_pot);
    printk(KERN_INFO "proc: Module unloaded.\n");
}
module_init(init_proc_module);
module_exit(cleanup_proc_module);



Makefile文件

obj-m    := test.o

KERNELS = /media/STUDY/linux/kernel/my2440-2.6.36
# KERNELS = /lib/modules/$(shell uname -r)/build/

default:
    make -C $(KERNELS) M=$(shell pwd) modules

.PHONY:clean
clean:
    make -C $(KERNELS) M=$(shell pwd) clean


make后插入模块test.ko, 会生成/proc/procfile文件
读文件/proc/procfile的内容(cat /proc/procfile)如下:

[root@zhanglong proc]# cat /proc/procfile
**********get the address information**********
current->comm: cat
current->state: 0
currentr->mm = 0xc3af0600
ttb = 0x33b28000
currentr->mm->pgd = 0xc3b28000
**********the virtual memory area***************
vm_area: 0x00008000 - 0x000a5000
vm_area: 0x000ac000 - 0x000ad000
vm_area: 0x000ad000 - 0x000ae000
vm_area: 0x000ae000 - 0x000b0000
vm_area: 0x40091000 - 0x400ad000
vm_area: 0x400b4000 - 0x400b5000
vm_area: 0x400b5000 - 0x400b6000
vm_area: 0x400be000 - 0x400bf000
vm_area: 0x400e5000 - 0x400e6000
vm_area: 0x400e6000 - 0x40184000
vm_area: 0x40184000 - 0x4018b000
vm_area: 0x4018b000 - 0x4018c000
vm_area: 0x4018c000 - 0x4018d000
vm_area: 0x401bb000 - 0x401c3000
vm_area: 0x401c3000 - 0x401ca000
vm_area: 0x401ca000 - 0x401cb000
vm_area: 0x401cb000 - 0x401cc000
vm_area: 0x401cc000 - 0x401f3000
vm_area: 0x401f3000 - 0x4030e000
vm_area: 0x4030e000 - 0x40316000
vm_area: 0x40316000 - 0x40318000
vm_area: 0x40318000 - 0x40319000
vm_area: 0x40319000 - 0x4031c000
vm_area: 0xbec9f000 - 0xbecc1000
total_vm: 0x2eb  locked_vm: 0x0  shared_vm: 0x29b        exec_vm: 0x280
code: 0x00008000 - 0x000a4458
data: 0x000acef4 - 0x000ad76d
brk: 0x001f8000 - 0x001f8000
start_stack: 0xbecc0e40
stack_vm: 34
arg_area: 0xbecc0f2d - 0xbecc0f40
env_area: 0xbecc0f40 - 0xbecc0ff3
len = 2594
[root@zhanglong proc]#

显然,s3c2440上linux应用程序的地址空间与x86机器上的linux应用程序的地址空间还是不同的。
阅读(1113) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~