註:以下大部分內容摘自linux核心編程入門篇和linux核心完全注釋
在工作的這段時間,發現我的visio畫圖熟悉了點點,總喜歡把什麼源碼啊,結構啊之類的就當作流程圖來畫來理解,因為對於圖,有一個很直觀的認識,所以接下去也是以圖為中心。
關於linux核心體繫結構
說到作業系統,我們都會知道windows作業系統,linux作業系統,蘋果的ios作業系統,以前很火的塞班作業系統,還有最近消費類電子很火的android作業系統。一個完整的作業系統分為4個部分。
可以把這個理解為我們用的手機。其中的硬體系統就是我們看到的整個手機了,cpu啊,記憶體啊,這些不拆開來看不到的,和觸控螢幕啊,按鍵之類看以看到的。作業系統核心就是我們說的android了,不過他包括了linux的核心了。作業系統服務就是android的一套結構了,給我們直觀的就是那個有點炫的介面了。我們可以通過點擊來實現我們想要的功能。使用者應用就是我們常玩的QQ啊,導航啊,當然少不了各種好玩的遊戲了,憤怒的小鳥,塗鴉跳,水果忍者,是不是又想玩一把。唉,還是好好學習吧,雖然手機就在旁邊。
對於linux核心的單核心模式的系統,有可以把他分為如下:
Linux核心又可分為5個大的模組。
其關係和主要功能可以見下圖:
關於linux記憶體
實體記憶體可以分為下圖所示:
核心佔用記憶體開始部分;接下來是共硬碟,磁碟片使用的高速緩衝區部分,其中扣除顯存和bios的640k到1m;然後是虛擬盤;最後一部分是為所有程式可以使用的主記憶體區。
Linux記憶體管理中,段變換:將一個由段選擇符和段內位移構成的邏輯地址轉換為一個線性地址。頁變換:將線性地址轉換為對應的物理地址。具體可見下圖所示:
虛擬位址:指的是由程式產生的由段選擇符和段內位移地址兩個部分組成的地址。為什麼叫它是虛擬地址呢。因為這兩部分組成的地址並沒有直接存取實體記憶體,而是要通過分段地址的變換機構處理或映射後才會對應到相應的實體記憶體地址。
段描述符:向CPU提供了將邏輯地址映射為線性地址所必要的資訊。描述符是由程式編譯器、連結器、載入器或者作業系統建立的。
描述符表:儲存描述符在描述符表中的,有兩類
1、 通用描述元表(Global descriptor table---GDT)
2、 局部描述符表(Local descriptor table---LDT)
描述符表是由8位元組構成的描述符項的記憶體中的一個數組。處理器是通過使用GDT和LDTR寄存器來定位GDT表和當前的LDT表。最多可以含有8192(2^13)個描述符。
選擇符:邏輯地址的選擇部分,用於指定一描述符的,它是通過指定一描述符表並且索引其中的一個描述符項完成的。
段寄存器:處理器將描述符中的資訊儲存在段寄存器中,因而可以避免在每次訪問記憶體時查詢描述符表。
線性地址:通過指定一個頁表、頁表中的某一頁以及頁中的位移值,從而間接地指向對應的物理地址。
頁表:一個簡單的32位頁指標的數組。頁表本身也是一頁記憶體,因此它含有4K位元組的記憶體,可容納1K個32位的項。
Offset = 2^12=4K, table =2^10, directory = 2^10,所以線性地址空間為2^10*2^10*4k=4G。
由於0.11核心把每個進程的最大可用的虛擬記憶體空間定義為64M,因此每個進程的邏輯地址可以用任務號*64M,就可以轉換到線性空間的地址。
關於linux進程
進程可以在核心態或者使用者態運行,當資源可用就被喚醒,進入就緒態;當進程處於可中斷睡眠狀態,收到訊號可被喚醒;當處於不可中斷睡眠狀態,只能被使用wakeup等的喚醒;當進程處於暫停狀態,可發送訊號使其進入就緒態;當僵死狀態,當已經停止運行,父進程還沒有調用wait查詢狀態,一旦父進程調用完wait取得子進程資訊後,這個進程任務資料結構就會被釋放掉。
關於linux檔案系統和源碼目錄
關於linux核心makefile
Linux makefile檔案是編譯協助工具輔助軟體make的參數設定檔。Make工具軟體的主要用途是通過識別哪些檔案已經被修改過,從而自動地決定在一個含有多個來源程式檔案的程式系統中哪些檔案需要被重新編譯。
這裡的makefile主要作用是指示make程式最終使用獨立編譯串連成的tools/目錄中的build執行程式將所有核心編譯代碼串連和合并成一個可啟動並執行核心映像檔案image。具體是對boot/目錄中的bootsect.s、setup.s使用8086彙編器進行編譯,分別產生各自的執行模組。再對原始碼中的其他所有程式使用GNU的編譯器gcc/gas進行編譯,並串連成模組system。再用build工具將這三塊組合成一個核心映像檔案image。