内核中如何得到进程描述符的地址
来源:互联网 发布:手机端淘宝链接转化 编辑:程序博客网 时间:2024/05/16 21:18
1.几个重要的结构:
<进程描述符>:struct task_struct 描述一个进程的所有信息的结构,包含众多描述进程属性的字段,以及指向其他与进程相关的结构体的指针
从上图可以得知,struct task_struct结构中存在如下重要的字段:
thread_info:struct thread_info,线程描述符,里面包含了指向进程描述符的指针mm: struct mm_struct,指向进程虚拟地址空间的结构fs: struct fs,包含进程的当前目录和根目录以及文件创建屏蔽字等信息的结构files: struct files_struct, 打开文件对象描述符结构signal: struct signal_struct, 与信号处理相关的结构
<线程描述符>:struct thread_info 其中包含指向进程描述符的指针,进程描述符地址的获取就是通过先得到thread_info的地址,再通过指针的引用得到task_struct的地址的,即thread_info->task
struct thread_info { struct task_struct *task; /* main task structure */ struct exec_domain *exec_domain; /* execution domain */ unsigned long flags; /* low level flags */ unsigned long status; /* thread-synchronous flags */ __u32 cpu; /* current CPU */ __s32 preempt_count; /* 0 => preemptable, <0 => BUG */ mm_segment_t addr_limit; struct restart_block restart_block; unsigned long previous_esp; __u8 supervisor_stack[0];};
2.获取struct thread_info结构的地址:
thread_info结构是存放到内核栈中的,一般情况下,内核栈是2页大小,即8k.而且内核栈的第一个页的页框起始地址是2^13的倍数. thread_info结构存放到内核栈的最低的地址处,大概有几十个字节的大小, 而内核栈的使用是从高地址向低地址延伸的.如下图所示:
上述情况的实现,在代码中的体现就是把线程描述符thread_info和内核栈的结构体放在一个联合体结构中,这样内核栈和thread_info就共用一个地址区域了
union thread_union { struct thread_info thread_info; unsigned long stack[THREAD_SIZE/sizeof(long)]; //内核栈的大小: sizeof(unsigned long)*(THREAD_SIZE/sizeof(long)) 即4×(8192/4) = 8192字节,即8k};
因为线程描述符的起始地址是位于内核栈的最低地址处,那么如果得到了内核栈的最低地址就得到了thread_info结构的地址,也就可以得到进程描述符的地址了
因为内核栈的第一页的起始地址是2^13的倍数,那么把内核栈的栈指针的最后13位屏蔽掉,也就得到了内核栈的最低地址(假设起始地址是2^13,那么内核栈的地址范围是2^13 ~ 2^14 - 1,则屏蔽最后13位后,结果为2^13,即内核栈的起始地址). 内核栈的栈指针保存在esp寄存器中.
static inline struct thread_info *current_thread_info(void){ return (struct thread_info *) (current_stack_pointer & ~(THREAD_SIZE - 1));}
在上面的代码中,当前的栈指针current_stack_pointer就是esp,
THREAD_SIZE为8K,二进制的表示为0000 0000 0000 0000 0010 0000 0000 0000.
~(THREAD_SIZE-1)的结果刚好为1111 1111 1111 1111 1110 0000 0000 0000,第十三位是全为零,也就是刚好屏蔽了esp的低十三位,最终得到的是thread_info的地址.
内核中经常是通过current宏来得到当前进程描述符的:
#define get_current() (current_thread_info()->task) #define current get_current()
本文引述自:
http://www.360doc.com/content/13/0905/13/7377734_312388669.shtml
http://edsionte.com/techblog/archives/2198
- 内核中如何得到进程描述符的地址
- 请问如何在内核中得到网卡的mac地址?根据网卡名子得到mac地址也可
- 在进程中用户态地址如何得到物理地址
- linux内核中得到进程全路径
- C#中如何得到机器的IP地址
- C#中如何得到机器的IP地址
- C#中如何得到机器的IP地址
- linux kernel中如何得到当前的进程信息
- 获取当前进程描述符地址 -- current
- linux 内核中得到 当前进程 对应的可执行文件的 绝对路径
- linux 内核中得到 当前进程 对应的可执行文件的 绝对路径
- Linux内核 2.4和2.6的进程内核堆栈和task描述符
- 如何得到当前页的地址
- 如何得到一个网站的后台地址
- 如何在驱动程序(SYS)中得到当前进程的完整路径和进程名
- 如何在驱动程序(sys)中得到当前进程的完整路径和进程名?
- 得到周的描述
- 如何得到本进程的CPU占用率?
- jquery 选择器
- 跨域资源共享(CORS)安全性浅析
- ImageLoad中的配置属性
- 将 Linux on x86 应用程序移植到 Linux on Power 的指南
- Unity常用代码
- 内核中如何得到进程描述符的地址
- 深入剖析Android音频之AudioSystem
- socket结束后如何立刻释放端口
- php-wamp环境搭建
- 淘宝框架历程
- 移除HTML5 input在type="number"时的上下小箭头
- mybatis返回List<Map<String,Object>>
- 如何实现servlet的单线程模式
- iOS获取UUID,并使用keychain存储