通过for_each_process(p)可以扫描整个进程链表。
其中p->mm值为0的任务就是所谓的内核线程。
从内核态的sp可以得到当前任务的指针: (sp & 0xffffe000)->task
对于s3c2440,外接的64MB的RAM的物理地址空间是0x30000000-0x34000000,
映射到0xc0000000-0xc4000000, 虚拟地址与物理地址相差0x90000000,与ttb和current->mm->pgd
之间相差0x90000000相符(在x86的cpu对应是0xc0000000)。
软/硬件环境:linux-2.6.36/s3c2440
test.c
-
#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;
-
int num = 0;
-
unsigned long ttb = 0;
-
unsigned long sp = 0;
-
struct task_struct *p;
-
struct vm_area_struct *vm = current->mm->mmap;
-
struct thread_info *thread;
-
-
memset(page, 0, MAX_COOKIE_LENGTH);
-
//从c2读ttb
-
__asm__ __volatile__ (
-
"mrc p15, 0, %0, c2, c0, 0\n"
-
"mov %1, r13\n"
-
:"=r" (ttb), "=r" (sp)
-
);
-
-
thread = (struct thread_info *)(sp & 0xffffe000);
-
-
sprintf(page + len, "***********************************************\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, "current = 0x%08x\n", current);
-
len = strlen(page);
-
sprintf(page + len, "thread->task = 0x%08x\n", thread->task);
-
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);
-
-
for_each_process(p){
-
num++;
-
sprintf(page + len, "%03d-[pid = %04d]-[mm = 0x%08x] comm: %s\n", num, p->pid, p->mm, p->comm); //
-
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模块。再执行命令cat /proc/procfile有如下输出:
[root@zhanglong proc]# cat /proc/procfile
***********************************************
current->comm: cat
current->state: 0
currentr->mm = 0xc3af8300
current = 0xc3893420
thread->task = 0xc3893420
ttb = 0x33a14000
currentr->mm->pgd = 0xc3a14000
001-[pid = 0001]-[mm = 0xc3a0f000] comm: init
002-[pid = 0002]-[mm = 0x00000000] comm: kthreadd
003-[pid = 0003]-[mm = 0x00000000] comm: ksoftirqd/0
004-[pid = 0004]-[mm = 0x00000000] comm: kworker/0:0
005-[pid = 0005]-[mm = 0x00000000] comm: kworker/u:0
006-[pid = 0006]-[mm = 0x00000000] comm: khelper
007-[pid = 0155]-[mm = 0x00000000] comm: sync_supers
008-[pid = 0157]-[mm = 0x00000000] comm: bdi-default
009-[pid = 0158]-[mm = 0x00000000] comm: kintegrityd
010-[pid = 0160]-[mm = 0x00000000] comm: kblockd
011-[pid = 0169]-[mm = 0x00000000] comm: khubd
012-[pid = 0172]-[mm = 0x00000000] comm: kseriod
013-[pid = 0176]-[mm = 0x00000000] comm: kmmcd
014-[pid = 0265]-[mm = 0x00000000] comm: rpciod
015-[pid = 0267]-[mm = 0x00000000] comm: kworker/0:1
016-[pid = 0273]-[mm = 0x00000000] comm: kswapd0
017-[pid = 0325]-[mm = 0x00000000] comm: fsnotify_mark
018-[pid = 0327]-[mm = 0x00000000] comm: aio
019-[pid = 0334]-[mm = 0x00000000] comm: nfsiod
020-[pid = 0342]-[mm = 0x00000000] comm: crypto
021-[pid = 0615]-[mm = 0x00000000] comm: kapmd
022-[pid = 0662]-[mm = 0x00000000] comm: mtdblock0
023-[pid = 0667]-[mm = 0x00000000] comm: mtdblock1
024-[pid = 0672]-[mm = 0x00000000] comm: mtdblock2
025-[pid = 0693]-[mm = 0x00000000] comm: kpsmoused
026-[pid = 0729]-[mm = 0x00000000] comm: usbhid_resumer
027-[pid = 0774]-[mm = 0xc3a0f480] comm: syslogd
028-[pid = 0777]-[mm = 0xc3a0f300] comm: inetd
029-[pid = 0781]-[mm = 0xc3a0f780] comm: boa
030-[pid = 0789]-[mm = 0xc3af8900] comm: qpe
031-[pid = 0790]-[mm = 0xc3af8480] comm: sh
032-[pid = 0791]-[mm = 0xc3a0f900] comm: init
033-[pid = 0793]-[mm = 0xc3a0f600] comm: init
034-[pid = 0795]-[mm = 0xc3a0fd80] comm: init
035-[pid = 0797]-[mm = 0x00000000] comm: kworker/u:2
036-[pid = 0801]-[mm = 0x00000000] comm: flush-0:14
037-[pid = 0808]-[mm = 0xc3af8000] comm: qss
038-[pid = 0809]-[mm = 0xc3af8600] comm: quicklauncher
039-[pid = 0815]-[mm = 0xc3af8300] comm: cat
len = 3130
[root@zhanglong proc]#
阅读(2199) | 评论(0) | 转发(0) |