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

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

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

書本重要知識回顧

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核心所使用的介面。