《Linux內核分析》第八週學習總結

《Linux內核分析》第八週學習總結算法

                                     ——進程的切換和系統的通常執行過程架構

姓名:王瑋怡  學號:20135116函數

1、理論部分總結學習

(一)進程切換的關鍵代碼switch_to的分析spa

一、進程調度與進程調度的時機分析操作系統

(1)調度策略線程

調度策略是一組規則,它們決定何時以怎樣的方式選擇一個新進程運行,不管何種策略,都是從運行隊列中選出一個進程做爲next來執行,Linux內核中的調度算法相關代碼使用了相似OOD中的策略模式。rest

(2)Linux的進程調度blog

  • 既支持普通的分時進程,也支持實時進程
  • Linux中的調度是多種調度策略和調度算法的混合
  • Linux的調度基於分時和優先級

   ——根據特定的算法計算出進程的優先級,用一個值表示隊列

   ——這個值表示把進程如何適當的分配給CPU

  • Linux中進程的優先級是動態的(調度進程會根據進程的行爲週期性的調整進程的優先級)

   ——較長時間未分配到CPU的進程,一般↑

   ——已經在CPU上運行了較長時間的進程,一般↓

(3)進程調度的時機——schedule()函數實現調度

  • 目的:在運行隊列中找到一個進程,把CPU分配給它
  • 調用方法:

  ——直接調用schedule()函數

  ——鬆散調用,根據need_resched標記

  • 調用時機

  ——用戶態進程經過中斷處理過程(包括時鐘中斷、I/O中斷,系統調用和異常)中,直接調用schedule(),或者返回用戶態時根據need_resched標記調用schedule()(用戶態進程只能被動調用),僅能經過陷入內核態後的某個時機點進行調度,即在中斷處理過程當中進行調度。

  ——內核線程(只有內核態,沒有用戶態的特殊進程)能夠直接調用schedule()進行進程切換,也能夠在中斷處理過程當中進程調度,也就是說內核線程做爲一類特殊d的進程能夠主動調用也能夠被動調用

二、進程上下文切換相關代碼分析

(1)進程上下文切換與中斷保存現場的區別

  進程上下文切換的是兩個不一樣的進程,而保存和恢復現場是在同一個進程中的工做。

  • 進程上下文包含了進程執行須要的全部信息

    用戶地址空間: 包括程序代碼,數據,用戶堆棧等

    控制信息 :進程描述符,內核堆棧等

    硬件上下文(注意中斷也要保存硬件上下文只是保存的方法不一樣)

(2)schedule()函數選擇一個新的進程來運行,並調用context_switch進行上下文的切換,這個宏調用switch_to來進行關鍵上下文切換

(3)關鍵語句

  • next = pick_next_task(rq, prev);//進程調度算法都封裝這個函數內部,包裝了其使用哪一種進程調度策略
  • context_switch(rq, prev, next);//進程上下文切換

    prepare_task_switch(rq, prev, next);//提早準備

    switch_to(prev, next, prev);//切換堆棧和寄存器狀態

      output:

      [prev_sp] "=m" (prev->thread.sp), //當前進程,內核堆棧的棧頂

      [prev_ip] "=m" (prev->thread.ip),//當前進程的eip

      input:

      [next_sp]  "m" (next->thread.sp),//下一個進程的內核堆棧的棧頂

      [next_ip]  "m" (next->thread.ip),//下一個進程的執行起點

      

      其中,第4四、45行完成了內核堆棧的切換,以後全部動做都在next內核堆棧中進行。

      next_ip通常是$if,對於新建立的子進程是ret_from_fork。

      jmp __switch_to經過寄存器傳遞參數。

(二)Linux系統的通常執行過程

一、Linux系統的通常執行過程分析 

最通常的狀況:正在運行的用戶態進程X切換到運行用戶態進程Y的過程

  • 正在運行的用戶態進程X
  • 發生中斷——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).
  • SAVE_ALL //保存現場
  • 中斷處理過程當中或中斷返回前調用了schedule(),其中的switch_to作了關鍵的進程上下文切換
  • 標號1以後開始運行用戶態進程Y(這裏Y曾經經過以上步驟被切換出去過所以能夠從標號1繼續執行)
  • restore_all //恢復現場
  • iret - pop cs:eip/ss:esp/eflags from kernel stack
  • 繼續運行用戶態進程Y

*關鍵:

  • 中斷和中斷返回的過程當中,有CPU上下文的切換
  • 進程調度的過程當中,有進程上下文的切換,是進程內核堆棧的切換

二、Linux系統執行過程當中的幾個特殊狀況

  • 經過中斷處理過程當中的調度時機,用戶態進程與內核線程之間互相切換和內核線程之間互相切換,與最通常的狀況很是相似,只是內核線程運行過程當中發生中斷沒有進程用戶態和內核態的轉換,不存在用戶態到內核態的權限變化
  • 內核線程主動調用schedule(),只有進程上下文的切換,沒有發生中斷上下文的切換,與最通常的狀況略簡略;
  • 建立子進程的系統調用在子進程中的執行起點(ret_from_fork)及返回用戶態,如fork(next_ip=ret_from_fork);
  • 加載一個新的可執行程序後返回到用戶態的狀況,如execve

三、內核與舞女、出租車。。。

  • 32位x86系統下,每一個進程大小爲4G,0~3G用戶態能夠訪問,3G以上只有內核態能夠訪問。
  • 全部進程3G以上的地址空間是共享的,內核是各類中斷處理過程和內核線程的集合,任何進程均可以陷入到內核態,而後返回到用戶態
  • 內核——出租車,進程——乘客

(三)Linux架構和執行過程概覽

一、Linux操做系統架構概覽

(1)操做系統

 

硬件資源最關鍵的是CPU和內存

(2)Linux操做系統的架構

 

二、執行ls命令——最簡單也是最複雜的操做

 

系統調用自己也是一種特殊的中斷,經過int 0x80進入內核態

COW(copy or write)寫時複製

三、從CPU和內存的角度看Linux系統的執行

 

2、實驗部分——理解進程調度時機跟蹤分析進程調度與進程切換的過程

一、搭建環境

 

二、加載符號表並鏈接到端口1234

三、設置斷點:schedule、context_switch、switch_to,其中switch_to 要明確位置

四、繼續運行到斷點1

五、繼續運行到斷點2

六、繼續運行到斷點3

此時,也能夠看到switch_to 的位置。

相關文章
相關標籤/搜索