1. 程式人生 > >基於Linux-3.9.4的mykernel實驗環境的極簡內核分析

基於Linux-3.9.4的mykernel實驗環境的極簡內核分析

一個 重新 第一次 分析 技術分享 win10 linux 以及 center

382 + 原創作品轉載請註明出處 + https://github.com/mengning/linuxkernel/

一、實驗環境

  win10 -> VMware -> Ubuntu16.04 -> QEMU -> linux-3.9.4

二、實驗目的

  1、了解在一個極簡內核中,為了實現多進程的切換,需要哪些必要的數據結構;

  2、了解對於一個OS來說,進程是如何啟動以及如何基於時間片輪轉對進程進行切換。

三、實驗結果

  技術分享圖片

圖 1 實驗結果 

四、代碼分析

  (1) 對應的PCB(進程控制塊)

   為了能夠實現進程的切換和正常運行,對於每一個進程,都需要有一些必要的資源、參數。比如,對應進程的唯一標識(pid)、進程的狀態(state)、每一個進程對應的堆棧(stack)、進程的入口地址(entry)、指向進程隊列中位於當前進程的下一進程指針(pnext)等等。

技術分享圖片

圖 2 PCB結構體定義

技術分享圖片

圖 3 進程切換的大致流程圖

  (2)進程切換的邏輯分析

  具體來講,對於進程的上下文切換,需要在平常的C代碼之間嵌入一些必要的匯編代碼,以保存將要被替換的進程的相關信息(現場)以及執行下一的進程,對於新的進程,也並非是從頭開始執行(第一次執行除外),而是從上一次被中斷的地方繼續開始執行。

               技術分享圖片

圖 4 進程切換中實現進程間上下文切換的匯編代碼

  (3)極簡內核的整體流程分析

            

                    技術分享圖片

圖 5 極簡內核整體運行流程圖

  在個人看來,該極簡內核的運行在本質上是一個死循環,在這個死循環中,基於固定時間片輪轉思想,修改進程切換標誌,在該死循環中查詢進程切換標誌,如果符合要求,則進行進程的切換,否則繼續執行當前進程,不進行進程切換。當然,這個死循環,是由內核中的0號進程觸發。0號進程是內核啟動起來,經過相應的初始化之後,執行的第一個進程。

             技術分享圖片

圖 6 my_start_kernel中對0號進程的初始化

   ·          技術分享圖片

圖 7 my_start_kernel中對進程鏈表的初始化(包括PCB初始化)

                    技術分享圖片

圖 8 my_start_kernel中執行的第一個進程(0號進程)

                    技術分享圖片

圖 9 時間片的實現(系統時鐘中斷      

 技術分享圖片

圖 10 0號進程死循環查詢是否執行進程切換

四、總結

  通過分析實驗代碼,比較清楚地了解一個簡單的時間片輪轉多道操作系統內核,了解了操作系統的中斷上下文和進程上下文切換。對於當前執行的進程來說,如果被分配到的時間片執行完,CPU 則會進行相應的進程切換。其中的調度程序,就是在維護一個就緒進程隊列,當進程用完屬於它的時間片後,在隊列中就會按照優先級重新排序。這種調度方式,應該是屬於一種比較簡單、公平同時也是比較高效的方式。

基於Linux-3.9.4的mykernel實驗環境的極簡內核分析