接著上篇cfs學習總結,下面對很久前看的一些linux核心的主要模組寫了個簡單的總結,本總結個人針對某個模組的回憶,並不針對原始碼,主要目的是一方面加強自己的記憶,另一方面提煉出一些東西與大家分享(有時候**看多了,對某個模組反而沒有了乙個整體的概念)。
一、linux啟動過程分析
linux的啟動過程可以分為四個階段:系統上電階段,bios階段,引導程式階段,linux核心階段。
(1)系統上電階段
對於x86體系結構來說,cpu上電後,eip = 0xffff fff0, cpu執行eip指向的指令,通常這是條跳轉指令,即跳轉到bios的入口。
(2)bios階段
bios主要完成兩個功能:加電自檢,即post(power on self test)和載入核心引導程式,這裡特指mbr(master boot record主引導記錄區512位元組),post過程主要完成系統硬體的檢測,比如記憶體檢測,系統匯流排檢測等。
(3)引導程式階段
這裡說的核心引導程式包括兩部分:mbr中的主引導程式和活動分割槽中的次引導程式。mbr中的主引導程式包含446位元組的程式和64位元組的磁碟分割槽表,主引導程式會掃瞄磁碟分割槽表,尋找活動的磁碟分割槽,將活動分割槽中的次引導程式載入到記憶體執行,次引導程式負責完成載入核心的任務。
(4)linux核心階段
核心被載入到記憶體後,首先為核心的執行做前期的準備,主要包括以下幾個主要步驟:
基本的思想就是在記憶體中找一塊安全的記憶體區,通常在核心資料段或堆結束的地方,在這段記憶體中將實體地址0開始的一段記憶體同時對映虛擬位址空間的0xc000 0000和0x0000 0000開始的位址處。
二、linux系統呼叫執行流程
linux系統呼叫的執行流程可以描述為:
(1)應用程式呼叫c庫中的函式
(2)c庫函式的實現為觸發int 0x80系統呼叫中斷,系統呼叫號在%eax中
(3)作業系統拿中斷向量號0x80查詢中斷向量表,執行對應的中斷處理函式
(4)中斷處理函式拿系統呼叫號%eax查詢系統呼叫表,執行相應的系統呼叫
(5)系統呼叫執行完成後返回應用程式
三、linux中斷分類和中斷處理過程
中斷的初始化主要包括:中斷向量表的初始化,中斷陣列的初始化,中斷處理函式的註冊等。
中斷產生和處理過程中硬體執行的操作:
裝置通過中斷請求線(irq線)向中斷控制器傳送乙個中斷訊號,中斷控制器接收到中斷訊號後,一方面經過解碼電路將中斷訊號轉化為中斷號,儲存在指定的io ports中,另一方面通過與cpu的intr管腳直接相連的int線向cpu傳送中斷訊號;
cpu收到中斷訊號後,等執行完當前指令,在執行下一條指令前,去檢查有無中斷處於pending狀態,如果有,通過inta向中斷控制器傳送響應訊號,並將中斷號通過data line取回,然後讀取idt表,獲得該中斷號對應的idt表中的第i項,然後根據idt[i]描述符中指定的段選擇子,去gdt表中查詢,獲得中斷處理程式的基址,然後用基址+idt[i]中指定的中斷處理程式的偏移位址,來獲得中斷處理程式的位址,當然,在讀取idt和gdt表時還會有一些安全性檢查。
cpu去判斷有沒有發生特權級的變化(使用者態陷入核心態),如果有,通過tr暫存器獲得tss段的基址,從中讀取核心態堆疊的ss和esp,此時就將使用者態的堆疊切換到了核心態的堆疊,接著將使用者態的ss和esp儲存在核心堆疊中,如果此中斷的型別是故障(fault),則重新修改cs和eip的值為產生中斷的這條指令的位址,以便中斷處理完成後,重新執行這條指令。然後,在核心棧中儲存eflags,cs和eip的值,如果有硬體出錯碼,也將其儲存到堆疊上,最後將cs:eip的值賦值為中斷處理函式的基址+idt[i]的偏移。
從使用者態進入中斷與從核心態進入中斷的堆疊示意圖如下。
在init_irq()中通過迴圈呼叫set_intr_gate(vector,interrupt[i])來初始化vector對應的idt表項,這裡的interrupt[256]陣列,通過下面的**把所有中斷的處理函式都定義為統一的入口:common_interrupt。
體系結構無關的中斷處理過程:do_irq()。
irq_desc資料報含了224個irq_desc_t描述符,每乙個中斷號對應乙個描述符,這個描述符中的action鍊錶,它指向irqaction的資料結構,代表這個中斷對應的處理函式,共享同一中斷向量的所有的處理函式都掛在這個鍊錶上,通過遍歷這個鍊錶,並查是否要是裝置註冊的處理函式(dev_id)。
軟中斷(softirq)由核心靜態分配,在編譯時就確定了,個數有限,目前核心支援8/9個,具有優先順序,主要與定時器,網路包的收發,塊裝置,排程,tasklet等有關。在特定的點檢查有無可執行的軟中斷:
(1)local_bh_enable重新啟用軟中斷時
(2)do_irq完成中斷處理過程後
(3)ksoftirqd被喚醒時
tasklet是i/o驅動程式中實現可延遲函式的首選,建立在軟中斷hi_softirq和tasklet_softirq之上,二者的區別是優先順序不同,這兩種tasklet由對應的陣列tasklet_vec和tasklet_hi_vec來管理,陣列的每一項對應乙個cpu,即tasklet是與cpu繫結的。
workqueue由工作佇列和工作者執行緒兩部分構成,工作者執行緒會定期的掃瞄工作佇列有無可處理的任務,軟中斷和tasklet執行在中斷上下文,所以不可睡眠,workquue執行在程序上下文,可睡眠。
Linux核心原始碼 閱讀方法
url 通常linux會有以下目錄 arch 子目錄包括所有和體系結構相關的核心 它還有更深的子目錄,每乙個代表一種支援的體系結構 include 子目錄包括編譯核心所需要的大部分 include 檔案。它也有更深的子目錄,每乙個支援的體系結構乙個。include asm 是這個體系結構所需要的真實...
Linux核心原始碼閱讀 1
1 作業系統的基本知識 2 對c語言比較熟悉,最好要有組合語言的知識和gnu c對標準c的擴充套件的知識的了解。另外在閱讀之前,還應該知道linux核心源 的整體分布情況。我們知道現代的作業系統一般由程序管理 記憶體管理 檔案系統 驅動程式 網路等組成。看一下linux內 核源 就可看出,各個目錄大...
Linux 核心程式設計總結
linux 核心程式設計總結 從事了幾年的核心程式設計,對核心程式設計有一定的經驗,現總結 吐槽下,作為標記。任何程序都有有程序的入口點,使用者態的程序,其入口點是,main函式。那麼核心的入口點是什麼?個人理解整個os,執行起來就是乙個程序,核心的入口點是init程序,在這個程序中負責 1 子程序...