Linux kernel 是狀態機還是結構化程式流程?
作業系統(Operating System)的研究,我們以 Linux kernel 的探討來說明一些應有的正確觀念。
對於 Linux kernel 的研究,最經常聽到有人提起「kernel source code」的研讀與分析,並且最常看到的研究方式為「尋找 kernel 進入點,並依照程式流程(flow)做循序研究」,不過,這卻是一種「大部份情況下都錯誤」的研究方式。
由於電腦系統是一種 foreground-background system,並且 Linux kernel 是在此系統上的作業系統,因此整體的 kernel 行為是「control patch」,也就是「控制權的轉移」與「系統狀態的改變」,並不是「程式(函數)流程(flow)」,或是「程式結構(structure)」的問題;最近有朋友問起這方面的議題, 正好也在進行 Linux device driver 的 training,因此特別整理這則日記,來與大家分享,若有任何論述上的失誤,或是有不同的觀點,歡迎在這裡留言 分享。
許多人對於「作業系統」的觀念可能真的有點薄弱;具體來說,對於 kernel 內部原理的研究,其方法應該是:
1. kernel 的開機階段,是以「流程(flow)」的角度來做討論。
2. kernel 完成開機後,會執行 init process,由此正式切換到 F/B system 的觀念,也就是整個系統是一個偌大的狀態機,整個系統內部是一連串複雜的控制權轉移動作。
最近朋友希望我能針對「kernel 的執行流程」做簡單介紹,但是這個問題在命題上應當有修正或是觀念澄清的空間。由於電腦本身是一種 foreground-background system,因此 foreground 的工作會影響 CPU 將控制權移交到 background 的哪一個部份;如果把 user-space 當成 foreground,kernel-space 當成 background,那麼整體系統便能以下圖表示。
Background 受到 foreground 行為的影響,拿以下二個 process 為例,雖然執行結果相同,但因為 foreground 內部的行為不同,因此 control path 也會不同:
/* Process P */ int main(void) { char buf[] = "Hello, World!"; printf("%s", buf); return 0; } /* Process Q */ #define STR "Hello, World!" int main(void) { char *buf; buf = malloc(strlen(STR)+1); strcpy(buf, STR); printf("%s", buf); return 0; }
此時,仍是以「流程圖」邏輯來思考的話,當然無法領會箇中奧妙。簡單二個不同的 process,CPU 將控制權移轉到作業系統的路徑(也就是 kernel 執行了哪些程式碼),居然有這麼大的差異。如果再把排程器(scheduler)加入,那麼整個控制路徑很可能「不同時間執行同一程式」也會不同。Tricky!
以研究方法來說,命題時觀念的失誤,終將無法得到正確且完善的結論,因此「希望就 kernel 的執行流程」做討論的命題,應當做修正,並且給定一個更明確的題目; 再者,若無法體認 kernel 是一個大型的狀態機,而仍以「流程與程式結構」的觀念來思考,除了在問題的描述會有相當大的誤差外,可能也會對「如何了解 kernel source code」的方法摸不著頭緒。
由此可知,整體系統在 kernel 開完機並執行 init process 後,就必須針對其「行為」做分析與研究,而不是徘徊在「結構化 C 程式」的圈圈裡;這個觀念證明了「逐行看 code」並不是研究 kernel 原理的正確方法。
Kernel 本身的行為是一連串複雜的狀態改變與控制權轉移,因此是狀態機的觀念。至於,研究方法是採用流程或是控制路徑的觀念進行,就看我們想要讀的是哪一個部份的 source code。前面提到研究 kernel 的二個階段與方式,當中的轉捩點為 init process,接續 init process,建議可先由 program execution(process creation)的觀念開始切入,以了解整個作業系統的行為。
所以,kernel 的研究,是以其動態(run-time)時期行為(behavior)的分析與觀察為主。
來源: www.jollen.org
Jollen's Blog 使用 Github issues 與讀者交流討論。請點擊上方的文章專屬 issue,或 open a new issue
您可透過電子郵件 jollen@jollen.org,或是 Linkedin 與我連絡。更歡迎使用微信,請搜尋 WeChat ID:jollentw