linux task_struct栈结构说明
struct thread_info {
struct task_struct *task;
struct exec_domain *exec_domain;
__u32 flags;
__u32 cpu;
mm_segment_t addr_limit;
__s32 preempt_count;
struct restart_block restart_block;
};
static inline struct thread_info *current_thread_info(void)
{
register unsigned long sp asm (“sp”);
return (struct thread_info *)(sp & ~THREAD_SIZE);
}
static inline struct task_struct * get_current(void)
{
return current_thread_info()->task;
}
#define current get_current()
找到current是通过thread_info结构,那么如何找到thread_info结构呢sp & ~THREAD_SIZE
这么看就比较清楚了 首先分配task_struct的时候申请THREAD_SIZE对应的页面数,所以task_struct的基地址的THREAD_SIZE-1 地址都为0,这样就可以根据sp(栈指针寄存器) 找到对应的task_struct结构。
最后再来解释下task_struct的数据结构
task_struct的第一个数据结构是state表示进程的状态。
第二个数据结构是thread_info指针 数据结构,
struct thread_info {
struct task_struct *task;
struct exec_domain *exec_domain;
__u32 flags;
__u32 cpu;
mm_segment_t addr_limit;
__s32 preempt_count;
struct restart_block restart_block;
};
剩下的数据结构一般都是描述给这个进程分配的资源。
当创建task_truct的时候会分配THREAD_SIZE个字节的内存,一般为4k或者8k,task_struct肯定是使用不了的,剩下的部分就用来存放thread_info结构,这个结构描述了task_struct的线程上下文,并且剩下的部分用于该进程的内核栈空间
栈底为图中bash+THREAD_SIZE处,栈顶最小到thread_info数据的最底部。
kthread_end判断是否栈底