linux中關於創建子進程系統堆棧的分析

2.6.24內核在task_struct結構中增加了一個void類型的指針stack,使它指向進程的系統空間堆棧頂端這是在do_fork()-->copy_process()-->dup_task_struct()函數中實現的:
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個字節.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章