Linux內核分析(八)

Linux內核分析——【實驗八:進程調度與切換】

一 進程調度的時機
(1)中斷處理過程(包括時鐘中斷、I/O中斷、系統調用和異常)中,直接調用schedule(),或者返回用戶態時根據need_resched標記調用schedule();
(2)內核線程可以直接調用schedule()進行進程切換,也可以在中斷處理過程中進行調度,也就是說內核線程作爲一類的特殊的進程可以主動調度,也可以被動調度;
(3)用戶態進程無法實現主動調度,僅能通過陷入內核態後的某個時機點進行調度,即在中斷處理過程中進行調度。

二 進程的切換
爲了控制進程的執行,內核必須有能力掛起正在CPU上執行的進程,並恢復以前掛起的某個進程的執行,這叫做進程切換、任務切換、上下文切換;掛起正在CPU上執行的進程,與中斷時保存現場是不同的,中斷前後是在同一個進程上下文中,只是由用戶態轉向內核態執行;
進程上下文包含了進程執行需要的所有信息:
(1) 用戶地址空間:包括程序代碼,數據,用戶堆棧等
(2) 控制信息:進程描述符,內核堆棧等
(3) 硬件上下文(注意中斷也要保存硬件上下文只是保存的方法不同)
schedule()函數選擇一個新的進程來運行,並調用context_switch進行上下文的切換,這個宏調用switch_to來進行關鍵上下文切換
next = pick_next_task(rq, prev);//進程調度算法都封裝這個函數內部
context_switch(rq, prev, next);//進程上下文切換
switch_to利用了prev和next兩個參數:prev指向當前進程,next指向被調度的進程

  schedule 函數路徑:/kernel/sched/core.c

8-0

switch_to 函數路徑:/arch/x86/include/asm/switch_to.h line 31

8-1

三 Linux系統的一般執行過程
最一般的情況:正在運行的用戶態進程X切換到運行用戶態進程Y的過程
(1)正在運行的用戶態進程X
(2)發生中斷——save cs:eip/esp/eflags(current) to kernel stack,then load cs:eip(entry of a specific ISR) and ss:esp(point to kernel stack).
(3) SAVE_ALL //保存現場
(4) 中斷處理過程中或中斷返回前調用了schedule(),其中的switch_to做了關鍵的進程上下文切換
(5)在標號1之後開始運行用戶態進程Y(這裏Y曾經通過以上步驟被切換出去過因此可以從標號1繼續執行)
(6) restore_all //恢復現場
(7) iret —— pop cs:eip/ss:esp/eflags from kernel stack
(8)繼續運行用戶態進程Y

注意:幾種特殊情況
(1)通過中斷處理過程中的調度時機,用戶態進程與內核線程之間互相切換和內核線程之間互相切換,與最一般的情況非常類似,只是內核線程運行過程中發生中斷沒有進程用戶態和內核態的轉換;
(2)內核線程主動調用schedule(),只有進程上下文的切換,沒有發生中斷上下文的切換,與最一般的情況略簡略;
(3)創建子進程的系統調用在子進程中的執行起點及返回用戶態,如fork;
(4)加載一個新的可執行程序後返回到用戶態的情況,如execve;

四 用gdb對schedule進行跟蹤
(1)實驗環境
跟實驗七一樣,在sys_execve處設置斷點,然後c執行,在QEMU中輸入exec,再在schedule處設置斷點。
8-2
(2)進行跟蹤
8-3
8-4
由於gdb不能直接跟蹤進入context_switch函數,所以只能找到它的源代碼看看了
8-5
以上就是進程調度和切換的大致過程。

五 linux系統的結構
8-6
最底層是硬件資源;其次是內核對硬件的接口,硬件製造商在生產硬件時必須滿足內核的接口,否則硬件無法匹配,硬件的功能也無法使用;然後是內核層,它包含了很多我們熟悉的東西,比如:文件系統/處理器調度/虛擬內存等等;再上來是系統調用接口;接着是一些系統庫函數/shell命令;最頂層也是我們最熟悉的用戶應用層。

=========== 王傑 原創作品轉載請註明出處==============
《Linux內核分析》MOOC課程http://mooc.study.163.com/course/USTC-1000029000

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章