struct thread_info *ti;
ti = alloc_thread_info(tsk);
if (!ti) {
free_task_struct(tsk);
return NULL;
}
*tsk = *orig;
tsk->stack = ti;
这里通过下面函数
#define alloc_thread_info(tsk) ((struct thread_info *) \
__get_free_pages(GFP_KERNEL, get_order(THREAD_SIZE)))
这里很明显其实就是分配系统的堆栈,并把地址转换成thread_info结构指针
这样就得到了系统的堆栈指针,然后同样通过copy_thread()-->task_pt_regs()
#define task_pt_regs(task) \
({ \
struct pt_regs *__regs__; \
__regs__ = (struct pt_regs *)(KSTK_TOP(task_stack_page(task))-8); \
__regs__ - 1; \
})
#define task_stack_page(task) ((task)->stack)
#define KSTK_TOP(info) \
({ \
unsigned long *__ptr = (unsigned long *)(info); \
(unsigned long)(&__ptr[THREAD_SIZE_LONGS]); \
})
好了我们再次看到上面的代码蓝色部分取出了刚才的系统堆栈指针,然后我们看到他有一个减8的计算,看一下这个图
为什么要减8呢,我们分析一下原来系统调用时或者中断时的情况,如果优先级别一样就不会把SS,ESP压入内核栈,这时候pt_regs结构体中的esp,xss不存在,为了防止非法访问,总在内核栈上空8个字节.