1. 程式人生 > >2018-2019-1 20189213《Linux內核原理與分析》第九周作業

2018-2019-1 20189213《Linux內核原理與分析》第九周作業

發生 ont linux操作 res 創建 簡單 系統調用 bubuko image

進程的切換和系統的一般執行過程

書本重要知識回顧

1.進程調度的時機
①中斷處理過程直接調用schedule(),或者當內核返回用戶態時根據need_resched標誌調用schedule()。
②內核線程是一個特殊的進程,只有內核態沒有用戶態,可以直接調用schedule()進行進程切換,也可以在中斷處理過程中進行調度(內核線程可以直接訪問內核函數,所以不會發生系統調用)。
③內核線程作為一類的特殊的進程可以主動調用schedule函數讓出CPU,也可以被動調度。
④用戶態進程無法實現主動調度,僅能在中斷處理過程中進行調度。

2.進程上下文切換
進程切換(或稱任務切換、上下文切換):為了控制進程的執行,內核必須有能力掛起正在CPU上執行的進程,並恢復以前掛起的某個進程的執行。
與中斷上下文的區別:掛起正在CPU上執行的進程,與中斷時保存現場是不同的,中斷前後是在同一個進程上下文中,只是由用戶態轉向內核態執行;而進程切換是在不同的進程之間進行調度。
進程上下文包含了進程執行需要的所有信息:
①用戶地址空間:包括程序代碼,數據,用戶堆棧等
②控制信息:進程描述符,內核堆棧等
③硬件上下文(註意中斷也要保存硬件上下文只是保存的方法不同,中斷:保存現場&恢復線程;進程調度:switc_to的機制)

核心代碼分析:schedule()函數選擇一個新的進程來運行,並調用context_switch進行上下文的切換,context_switch中的一個關鍵宏switch_to來進行關鍵上下文切換。
①next = pick _ next _ task(rq, prev)//封裝了使用的某種進程調度策略,選擇一個進程作為next
②context_switch(rq, prev, next)//實現進程上下文切換
③switch_to切換寄存器的狀態和堆棧,利用兩個參數:prev指向當前進程,next指向被調度的進程。
技術分享圖片
3.Linux系統的運行過程
正在運行的用戶態進程X切換到運行用戶態進程Y的過程:
①正在運行的用戶態進程X。
②發生中斷——save cs:eip/esp/eflags(當前進程CPU的狀態壓入用戶態進程X的內核堆棧)——load cs:eipss:esp(加載中斷服務例程和內核堆棧)。
③進入中斷處理進程,首先SAVE_ALL,保存現場。
④中斷處理過程中或中斷返回前調用了schedule(),其中的switch_to做了關鍵的進程上下文切換。
⑤標號1之後開始運行用戶態進程Y(這裏Y曾經通過以上步驟被切換出去過因此可以從標號1繼續執行)。
⑥restore_all 恢復進程X的執行狀態。
⑦iret - pop cs:eip/ss:esp/eflags from kernel stack,
⑧繼續運行用戶態進程Y。從Y進程的內核堆棧中彈出②中硬件完成的堆棧內容。
幾種特殊情況:
①通過中斷處理過程中的調度時機,用戶態進程與內核線程之間互相切換和內核線程之間互相切換,與最一般的情況非常類似,只是內核線程運行過程中發生中斷沒有進程用戶態和內核態的轉換;
②內核線程主動調用schedule(),只有進程上下文的切換,沒有發生中斷上下文的切換,比 最一般的情況略簡略;
③創建子進程的系統調用在子進程中的執行起點及返回用戶態,如fork一個子進程時;
④加載一個新的可執行程序後返回到用戶態的情況,如execve系統調用加載新的可執行程序;

4.Linux系統構架與執行過程概覽
典型的linux操作系統的結構:
技術分享圖片
最簡單也是最復雜的操作ls:
技術分享圖片
從內存的角度看Linux的系統執行:
技術分享圖片

實驗:理解進程調度時機跟蹤分析進程調度與進程切換的過程

主要使用gdb跟蹤分析一個schedule()函數,首先進入實驗樓環境,配置運行MenuOS系統:
技術分享圖片
技術分享圖片
配置gdb遠程調試和設置斷點,其中switch_to是宏定義,無法添加:
技術分享圖片
按c執行,停在schedule函數斷點處,發現調用了schedule(),即發生了進程調度:
技術分享圖片
按c繼續執行到pick_next_task斷點處:發現在這裏使用了某種調度策略選擇下一個進程來切換;
技術分享圖片
按c繼續執行到context_switch斷點處:context_switch用來實現進程的切換;
技術分享圖片


單步調試進入switch_to函數內部:
技術分享圖片
context_switch首先調用switch_mm切換CR3,然後調用宏switch_to來進行硬件上下文切換。

總結

①linux進程調度是基於分時和優先級的。
②在linux中,進程主動調度的時機可以在中斷處理過程中、內核線程中,但用戶態進程無法實現主動調度,僅能通過陷入內核態的新時機點進行調度,即在中斷處理過程中進行調度。
③內核線程是只有內核態沒有用戶態的特殊進程。
④linux內核調用schedule()函數進行進程調度,並調用context_switch進行上下文的切換,調用switch_to來進行進程關鍵上下文切換。
⑤linux系統的一般執行過程可以抽象成正在運行的用戶態進程X切換到運行用戶態進程Y的過程。
⑥內核可以看作各種中斷處理過程和內核線程的集合。
⑦本書前面的章節覆蓋了進程管理的相關內容,本章則考察了進程調度所遵循的基本原理、具體實現、調度算能以及目前Linux內核所使用的接口。

2018-2019-1 20189213《Linux內核原理與分析》第九周作業