pianogirl 原創作品轉載請注明出處 + 《Linux內核分析》MOOC課程http://mooc.study.163.com/course/USTC-1000029000
總博客列表:pianogirl123
一、引子
1、Linux操作系統的縮影————mykernel
mykernel這樣一個短小精悍的模擬內核,時常給我提供了看問題的角度和思路。當被龐雜的Linux內核代碼弄得一頭霧水時,我就去看看mykernel,很多復雜的問題就可以用簡單的機制解釋。
2、從mykernel出發縱觀全課程
mykernel幾乎串起了整個課程:
- 匯編————x86匯編基礎
- 內核啟動my_start_kernel()————MenuOS的啟動
- fork more process————進程的創建與描述
- 如果使用fork()創建進程的話————系統調用(上)、系統調用(下)
- my_time_handler()————進程的切換與調度機制
- task[pid].thread.ip————可執行程序的裝載
課本博客鏈接:
《Linux內核設計與實現》——第1、2章(內核簡介)
《Linux內核設計與實現》——第3章(進程管理)
《Linux內核設計與實現》——第4章(進程調度)
《Linux內核設計與實現》——第5章(系統調用)
《Linux內核設計與實現》——第18章(調試)
二、要點梳理
1、函數調用框架
總結:
進入另一個函數之前,總是保存當前棧的基地址,開始一個新的棧,使每個函數有獨立的棧空間,當函數返回時,能恢復到之前函數的棧空間。
結構清晰,層次鮮明,使人不得不佩服機器處理數據的嚴謹與清晰。
2、內核的啟動
一句話啟動Linux內核:
qemu -kernel (該版本的Kernel所在路徑) -initrd (rootfs.img)
qemu :相當於打開一個虛擬機
kernel:啟動一個內核,位置由其後的文件名指定。
initrd指令:掛了一個ramdisk虛擬硬盤,是內核的重要補充,rootfs.img就是這個虛擬硬盤,內有分區,然後啟動其中的init.init是由之前編譯而成,gcc -o命名為init。
道生一,一生二,二生三,三生萬物:
rest_init()這個函數調用系統函數 kernel_thread() 創建 1 號進程,即 init 進程,是用戶態所有進程的祖先。然後,新建 kthreadd 進程,2號進程,是內核態所有進程的祖先。最後,通過 cpu_startup_entry 函數啟動 0 號進程。
3、進程的描述、創建,上下文切換,調度策略
(1)進程的描述、創建
下圖為個人理解,如有不當請老師指正!
【我畫的圖是一般的兩個進程在內存中的情況,包括各自的堆棧空間、PCB板(保存了各個進程自己的sp、ip)、數據、以及切換時SAVE_ALL保存當時寄存器所有數值的情形。】
上面那張我畫的圖是一般的兩個進程在內存中的情況,但是也可以幫助我們理解系統是
怎樣fork一個子進程並返回到用戶態的。 博客鏈接
(2)進程上下文切換
參照上圖,可以幫助理解
兩個進程間是怎麼切換的 博客鏈接
(3)調度策略
Linux針對實時進程、非實時進程采取不同的調度策略,見:
《Linux內核設計與實現》————第4章(進程調度)
4、系統調用
這張圖非常清晰地描述了系統調用的層次和原理。
系統調用總控程序(system_call)是操作系統提供給應用程序的一個特殊接口,特殊之處在於是利用軟中斷陷入內核。對i386的CPU,就是執行INT 0x80中斷(“系統調用”),同時將CPU切換到核心態。
進程在執行陷入前把系統調用號裝入eax,接著系統調用總控程序負責將系統調用號派發到各自的服務例程,然後調用它執行。
三、思考與總結
1、思考
理解操作系統原理的形象化方法:和日常生活聯系起來。操作系統辦事情很多出發點和我們是一樣的。
怎麼理解中斷上下文和進程上下文切換? 可以想象個場景,例如,我們工作時突然來了一個打擾(如電話),需要把手頭工作進行到哪裡了保存在大腦裡,方便接完電話後繼續回到工作狀態。不論是中斷上下文還是進程上下文的切換,都是基於這個原理。
怎麼理解內核態和用戶態? 打個比方,圖書館中,讀者可以自由地檢索目錄、閱讀書籍,卻無權直接去書庫取書,也無權修改圖書館的數據庫。而工作人員就在特權狀態,可以訪問任意資源。這樣的劃分是為了系統的穩定和安全,也是免去了用戶和系統底層打交道的麻煩。
怎麼理解系統調用? 圖書館中,讀者想要借書時,只能填寫借書單,由工作人員完成登記和取書工作。“借書單”起到了一個“接口”的作用。在系統中運行的應用程序通過系統調用與內核通信,也是通過系統調用界面陷入內核。而“接口”是實現的關鍵。
2、收獲
彌補了匯編和操作系統的知識盲區,加深對計算機底層的理解,見識了很多C語言中不曾接觸過的高級內容(如宏、條件編譯),理解了linux的思想——“提供機制,instead of策略”。
3、遺憾
只能做到宏觀上理解,然而很多問題都是不求甚解的狀態,尤其涉及到內核C代碼,很多沒見過的語法和數據結構讓我很迷糊。