內(nèi)核在創(chuàng)建進程時牧嫉,會同時創(chuàng)建task_struct和進程相應(yīng)堆棧。每個進程都會有兩個堆棧减途,一個用戶棧酣藻,存在于用戶空間,一個內(nèi)核棧鳍置,存在于內(nèi)核空間辽剧。當(dāng)進程在用戶空間運行時,CPU堆棧寄存器的內(nèi)容是用戶堆棧地址税产,使用用戶棧怕轿。當(dāng)進程在內(nèi)核空間時,CPU堆棧寄存器的內(nèi)容是內(nèi)核棧地址空間辟拷,使用的是內(nèi)核棧撞羽。
當(dāng)進程因為中斷或系統(tǒng)調(diào)用進入內(nèi)核時,進程使用的堆棧也需要從用戶棧到內(nèi)核棧衫冻。進程陷入內(nèi)核態(tài)后诀紊,先把用戶堆棧的地址保存到內(nèi)核堆棧中,然后設(shè)置設(shè)置CPU堆棧寄存器為內(nèi)核棧的地址隅俘,這樣就完成了用戶棧到內(nèi)核棧的轉(zhuǎn)換邻奠。
當(dāng)進程從內(nèi)核態(tài)恢復(fù)到用戶態(tài)時,把內(nèi)核中保存的用戶態(tài)堆棧的地址恢復(fù)到堆棧指針寄存器即可为居。這樣就實現(xiàn)了內(nèi)核棧到用戶棧的轉(zhuǎn)換碌宴。
注意:陷入內(nèi)核棧時,如何知道內(nèi)核棧的地址呢蒙畴?
進程由用戶棧到內(nèi)核棧轉(zhuǎn)換時贰镣,進程的內(nèi)核棧總是空的忍抽。每次從用戶態(tài)陷入內(nèi)核時八孝,得到的內(nèi)核棧都是空的,所以在進程陷入內(nèi)核時鸠项,直接把內(nèi)核棧頂?shù)刂方o堆棧指針寄存器即可。