您當前的位置:首頁 > 舞蹈

Linux核心分析-作業系統是如何工作的(二)

作者:由 Linux分享官 發表于 舞蹈時間:2020-09-17

linux作業系統的主要構架如圖1所示,我們知道,作業系統是透過管理CPU程序、儲存器、檔案系統、裝置驅動、以及網路介面等相關部分來工作的,我們這裡主要是透過分析關於CPU的操作即程序的管理執行來分析linux作業系統是怎樣工作的。

Linux核心分析-作業系統是如何工作的(二)

圖1 linux作業系統核心結構

一 linux作業系統工作的基礎

linux作業系統的正常工作可以說有三個非常重要的部分,就是我們的儲存程式原理、堆疊以及中斷的支援。

1.儲存程式計算機

我們都知道,馮。諾依曼體系結構為計算機的發展提供了不可磨滅的作用,馮。諾依曼的主要貢獻就是提出並實現了“儲存程式”的概念。

按照馮·諾依曼儲存程式的原理,計算機在執行程式時須先將要執行的相關程式和資料放入記憶體儲器中,在執行程式時CPU根據當前程式指標暫存器的內容取出指令並執行指令,然後再取出下一條指令並執行,如此迴圈下去直到程式結束指令時才停止執行。那麼我們就可以將計算機的工作過程簡化成如下圖2所示。

Linux核心分析-作業系統是如何工作的(二)

圖2計算機基本工作原理

而我們的linux作業系統就是以儲存程式計算機的工作原理為基礎去管理整個計算機以及整個計算機的執行工作流程。

2.棧

程序是CPU執行的基本單位,每個程序都有自己獨立的記憶體空間,程序的記憶體地址空間如附錄一所示。當然我們這裡要說的就是程序的使用者態的佔空間以及8KB的核心棧,由於虛擬儲存技術,每個程序都感覺自己享有完整的記憶體空間,在這裡不加贅述。

棧為我們的函式呼叫以及程序的切換等等提供了不可磨滅的作用。當我們進行函式呼叫的時,使用者態的棧會儲存我們的返回地址、相關暫存器、函式引數以及區域性變數等等一些相關條件;當我們進行系統呼叫或者其它中斷的時候,核心棧會同樣為我們儲存返回地址、相關暫存器等一些相關資訊,可以說棧是我們系統的正常執行必不可少的條件。

3.中斷

中斷是指當出現需要時,CPU暫時停止當前程式的執行轉而執行處理新情況的程式和執行過程。中斷技術的出現為多工計算機提供了不可磨滅的作用,中斷使得程序能夠併發的去執行,大大提高了CPU的利用率。中斷是多程序能夠正常執行以及程序間的切換的必不可少的要素。

以上的三方面是linux作業系統正常工作管理必不可少的部分。我們知道,程序是CPU執行的單位(這裡暫時不考慮執行緒),下面我們透過分析核心是如何管理程序來實現任務的正常進行。

二 核心工作的微觀分析

作業系統對程序的管理主要就是程序的管理和排程,我們為每個程序維護一個程序描述和以及程序間的關係。我們的核心的工作主要有兩部分組成,首先執行有一個核心執行緒,然後就是一些中斷處理程式的集合,我們在中斷處理程式中要就行程序的排程。下面主要分析核心是如何執行程序的切換以及排程來實現作業系統的正常執行。

如圖3所示,當前程序X在執行,當前的esp暫存器指向程序X的使用者棧,eip指向程序X的程式碼區,假設程序X的時間片用完,這時候發生中斷,那麼CPU要做兩件工作,1是將當前的eip和esp壓入到程序X的核心棧,2是將esp指向程序X的核心棧,並將eip指向中斷處理入口,進入到核心態。在進行SAVA_ALL即儲存相關暫存器等之後,開始執行中斷處理程式,進行的切換與排程就是發生在中斷處理程式中。我們會根據相應的排程策略,選擇下一個要執行的程序Next,並切換到程序Next。這裡核心是透過執行switch_to(switch_to的程式碼見附錄一所示)來進行程序切換的,在switch_to中我們主要進行了程序的暫存器register和程序的核心棧stack的切換。當程序切換完以後,我們的esp就指向了程序Y的核心棧,我們可以看到,在程序Y的核心棧中儲存著程序Y被掛起以前的esp以及eip,我們程序彈棧操作,那麼我們現在的eip指向的就是我們程序Y的程式碼區,而esp就只想程序Y的使用者棧,這樣透過esp和eip的的切換我們就切換到了程序Y繼續執行,完成了整個程序從X切換到程序Y。

Linux核心分析-作業系統是如何工作的(二)

圖3 中斷以及程序切換和排程

附錄一 程序的地址空間

Linux核心分析-作業系統是如何工作的(二)

附錄二 switch_to原始碼

#define switch_to(prev,next,last) do{ \

unsigned long esi,edi; \

asmvolatile(“pushfl\n\t” /* Saveflags */ \

“pushl %%ebp\n\t” \

“movl %%esp,%0\n\t” /* save ESP */ \

“movl %5,%%esp\n\t” /* restore ESP */ \

“movl $1f,%1\n\t” /*save EIP */ \

“pushl %6\n\t” /*restore EIP */ \

“jmp __switch_to\n” \

“1:\t” \

“popl %%ebp\n\t” \

“popfl” \

:“=m” (prev->thread。esp),“=m”(prev->thread。eip), \

“=a” (last),“=S” (esi),“=D” (edi) \

:“m” (next->thread。esp),“m”(next->thread。eip), \

“2” (prev), “d” (next)); \

} while (0)

首先恭喜您,能夠認真的閱讀到這裡,如果對部分理解不太明白,建議先將文章收藏起來,然後對不清楚的知識點進行查閱,然後在進行閱讀,相應你會有更深的認知。如果您喜歡這篇文章,就點個贊或者【關注我】吧!!

標簽: 程序  核心  ESP  執行  中斷