linux核心閱讀總結

來源:互聯網
上載者:User
 接著上篇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核心階段

核心被載入到記憶體後,首先為核心的運行做前期的準備,主要包括以下幾個主要步驟:

  • 設定c程式啟動並執行堆棧
  • 清空BSS段
  • 設定中斷描述符表(IDT)
  • 設定通用描述元表(GDT)
  • 置位CR0的PE位,開啟保護模式(保護模式開啟後必須緊跟一條長跳轉指令,用來清空指令預取隊列,並重新設定%CS段寄存器)
  • 調用核心解壓函數 – decompress_kernel(),並跳轉到解壓核心的入口
  • 設定CR0的PG位,開啟分頁機制

基本的思想就是在記憶體中找一塊安全的記憶體區,通常在核心資料區段或堆結束的地方,在這段記憶體中將物理地址0開始的一段記憶體同時映射虛擬位址空間的0xC000 0000和0x0000 0000 開始的地址處。

  • 跳轉到start_kernel
二、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]的位移。

從使用者態進入中斷與從核心態進入中斷的堆棧如下。

IDT表的初始化:通過set_intr_gate()和trap_init(),後者用於初始化20個異常和一個系統調用相關的中斷0x80。

在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運行在進程上下文,可睡眠。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.