王瑋怡 + 《Linux內核分析》MOOC課程http://mooc.study.163.com/course/USTC-1000029000html
《Linux內核分析》期末總結算法
姓名:王瑋怡 學號:20135116編程
1、博客目錄:數據結構
一、第一週學習總結:計算機是如何工做的?框架
二、第二週學習總結:操做系統是如何工做的?函數
三、第三週學習總結:構造一個簡單的Linux系統MenuOS學習
四、第四周學習:扒開系統調用的三層皮(上)ui
五、第五週學習總結:扒開系統調用的三層皮(下)spa
六、第六週學習總結:進程的描述和進程的建立操作系統
七、第七週學習總結:可執行程序的裝載
八、第八週學習總結:進程的切換和系統的通常執行過程
2、課程總結
一、計算機是如何工做的?
主要介紹一些基礎知識,包括彙編語言基礎知識、C語言函數調用過程當中的堆棧變化和參數傳遞過程。
- 存儲程序計算機工做模型——馮諾依曼體系結構。
- 程序:告訴計算機操做的步驟、輸入的數據、如何存放處理後的結果。
- 彙編語言:彙編語言是機器語言的一種翻譯。
二、操做系統是如何工做的?
簡單模擬內核代碼。主要包括函數調用堆棧、函數堆棧框架、內核的初始化、中斷、進程上下文切換過程的簡述以及基於時間片輪轉的多道程序模擬。
- 操做系統三個法寶:存儲程序計算機、函數調用堆棧、中斷機制。
- 操做系統兩把寶劍:中斷上下文、進程上下文的切換。
- 中斷:多道程序設計,能夠多個程序同時運行,當一箇中斷髮生時,由CPU和內核代碼共同實現了保存現場和恢復現場。
- 操做系統核心功能:進程調度和中斷機制,經過與硬件的配合實現多任務處理,再加上上層應用軟件的支持,最終變成可使用戶能夠很容易操做的計算機系統。
- 進程切換:當正在運行的進程等待其餘的系統資源時,Linux內核將取得CPU的控制權,並將CPU分配給其餘正在等待的進程。進程切換機制中包含esp的切換、堆棧的切換。
三、構造一個簡單的Linux系統MenuOS
這一週內,咱們學習了閱讀內核源碼和構造Linux系統MenuOS,主要包括源碼主要結構、內核啓動及調試方法和start_kernel的解讀。咱們總結爲:道生一(start_kernel
-->cpu_idle
),一輩子二(kernel_init
和kthreadd
),二生三(即前面0、1和2三個進程),三生萬物(1號進程是全部用戶態進程的祖先,2號進程是全部內核線程的祖先)
- 內核啓動完成進入menu程序,支持三個命令quit、version、help
- ipc和進程通訊相關的目錄
四、扒開系統調用的三層皮(上)
關於系統調用的知識。主要包括對系統調用與用戶態、內核態的理解、經過編寫彙編代碼瞭解系統調用機制。
- Intel x86 CPU有四種不一樣的執行級別0-3,Linux只使用了0級和3級分別表示內核態和用戶態。
- 0xc0000000以上的邏輯地址空間只能在內核態下訪問,0x00000000-0xbfffffff的邏輯地址空間在兩種狀態下都能訪問。
- 中斷處理是從用戶態進入內核態的主要方式,而系統調用只是一種特殊的中斷。
- 中斷處理的完整過程:
![](http://static.javashuo.com/static/loading.gif)
- 操做系統提供的API(應用編程接口)和系統調用的關係:並不是一一對應
- 系統調用的三層皮:xyz、system_call和sys_xyz
![](http://static.javashuo.com/static/loading.gif)
- 在Linux中經過int$0x80來執行系統調用——產生向量爲128的編程異常
- 進程須要經過傳遞一個名爲系統調用編號的參數來指明須要哪一個系統調用(經過eax寄存器來實現傳遞)——系統調用號將xyz和sys_xyz關聯起來
- system_call是Linux中全部系統調用的入口點,每一個系統調用至少有一個參數,即由eax傳遞的系統調用號
五、扒開系統調用的三層皮(下)
本週實驗須要咱們添加一個本身編寫的系統調用,加深對系統調用在內核代碼中的處理過程的理解。
- 第一步,SAVE_ALL保存現場。
- 第二步,肯定中斷信息,將系統調用號經過eax傳入,經過
sys_call_table
查詢到調用的系統調用,而後跳轉到相應的程序進行處理。
- 第三步,處理中斷。
- 第四步,
RESTORE_ALL
恢復系統調用時的現場,iret返回用戶態。
六、進程的描述和進程的建立
這周咱們主要學習了關於進程的描述和建立。主要包括PCB的組織形式、進程的數據結構進程描述符、fork系統調用的關鍵執行過程。
- 操做系統三大功能:進程管理(核心)、內存管理、文件系統
- PCB task_struct中包含:進程狀態、進程打開的文件、進程優先級信息
- 進程控制塊PCB——進程描述符task_stuck提供了內核所需瞭解的進程信息
- 進程的建立:start_kernel ...cpu_idle -->kernel_init和kthreadd -->0、一、2號進程(其中1號進程是全部用戶線程的祖先,2號進程是全部內核線程的祖先)
- fork()系統調用:在用戶態建立一個子進程,在父進程和子進程中各會返回一次,在子進程中pid的返回值爲0,在父進程中的返回值爲子進程的pid
- p->thread.ip = (unsigned long) ret_from_fork; //調度到子進程時的第一條指令
七、可執行程序的裝載
本週咱們學習了關於程序的加載過程和ELF文件格式。主要包括獲得一個可執行程序過程、ELF文件格式的結構和靜態連接、可執行程序的靜態加載過程和動態加載過程。
- 連接器的兩個任務:符號解析、重定位
- 目標文件的三種形式:可重定位目標文件(編譯器和彙編器可生成)、可執行目標文件(連接器可生成)、共享目標文件(編譯器和彙編器可生成)
- 新的可執行程序起點——通常是地址空間爲0x8048000或0x8048300
- execve執行靜態連接程序時,經過修改內核堆棧中保存的eip的值做爲新進程的起點
- 動態鏈接有兩種形式:可執行程序裝載時動態鏈接和運行時動態連接
- 運行時動態裝載連接至少須要用到dlopen、dlsym函數
八、進程的切換和系統的通常執行過程
本週咱們主要學習了關於進程切換和總體執行過程。主要包括Linux進程調度算法簡介、進程切換代碼分析、switch_to理解、進程相關的數據結構簡析。
- Linux進程調度是基於分時和優先級的
- Linux中,內核線程是隻有內核態沒有用戶態的特殊進程
- 內核能夠看做各類中斷處理過程和內核線程的集合
- 用戶態進程沒法主動調度,只能經過系統調用或其餘中斷陷入內核的時機進行調度
- Linux中,內核線程能夠主動調度,主動調度時不須要中斷上下文的切換
- Linux內核調用schedule()函數進行調度,並調用context_switch進行上下文的切換,這個宏調用switch_to來進行關鍵上下文切換。
- 進程調度的時機——schedule()函數實現調度
3、感想
一、收穫
(1)Linux操做系統之前是沒有接觸過的,經過此次的學習有又學習到新知識,才知道原來在平常生活中也是很常見的。
(2)基本瞭解了Linux內核的相關結構和設計原理,學會gdb調試及相關代碼分析方法。
(3)在每一週互評博客的過程當中,會發現不少好的總結,對個人學習也是一種補充。
二、遺憾
(1)儘管已經學習完了,但仍是以爲這門課很難,有些內容仍是沒有徹底理解。
(2)經過此次的學習,咱們瞭解了Linux內核的相關知識,可是想要靈活使用Linux操做系統還須要之後繼續努力~