现在的位置: 首页 > 综合 > 正文

内核如何获取thread_info的地址以及task的地址

2014年12月10日 ⁄ 综合 ⁄ 共 1611字 ⁄ 字号 评论关闭

1.通过thread_union,使进程内核态堆栈和thread_info紧密结合在一起。

文件include/linux/sched.h当中,有thread_union的定义

 

2.esp指向的是内核堆栈的结尾,由于堆栈是向下增长的,esp和thread_info位于同一个8KB或者4KB的块当中。

也就是thread_union的长度了。如果是8KB,屏蔽esp的低13位就可以得到thread_info的地址,也就是8KB块

的开始位置。4KB的话,就屏蔽低12位。

在文件include/asm-x86/thread_info_32.h当中我们可以看到current_thread_info()函数调用是如何实现的。

直接返回thread_info指针,当前的堆栈指针current_stack_pointer,也就是esp,THREAD_SIZE为块的字节大小

8192或者是4096,这里假设值8192,十六进制的表示是0x00002000,二进制的表示是00000000000000000010000000000000

~(THREAD_SIZE-1)的结果刚好为1111111111111111111 0000000000000,第十三位是全为零,也就是刚好屏蔽了esp的低十三位,最终得到的是thread_info的地址。

 

可以用汇编语言描述,更加直观:

最后p中就包含了,thread_info的地址了。

 

3.获取进程描述符的地址

我们先看看thread_info这个结构的具体定义,在文件中。

要获取进程描述符,也就是task指针,上面可以看到,其在thread_info结构当中的偏移量刚好是0,所以上面也就是获得了task指针,也就是进程描述符的指针。

抱歉!评论已关闭.