1. 程式人生 > >全面解析Linux 內核 3.10.x - 如何開始

全面解析Linux 內核 3.10.x - 如何開始

一定的 initrd system 格式 配額 read 結果 kcon csdn

萬事開頭難 - 如何開始?

人總是對未知的事物充滿恐懼!就像航海一樣,在面對危難的時候,船員和船長是一樣心中充滿恐懼的!只是船員始終充滿恐懼,而船長卻能壓抑恐懼並從當前找出突破口!
我沒有船長之能,但也算入行兩年的老船員,我會追隨船長一起尋找突破口!而內核如此龐然大物不知從何入手這真的很正常,那麽應該的入口在哪裏?其實我也不知道,一千個讀者就有一千個哈姆雷特。每個人都入口的理解都不一樣,有人說是必須有著良好的C編程經驗,有人說必須有著對Linux發行版等必要的操作經驗,也有的人說一定要數據結構理解的很好,還有的人說你必須的對各種架構的匯編了如指掌!眼花撩亂的知識你又掌握了多少呢?

我列出三點

1.必須有著良好的C語言理解能力,尤其是指針(靈魂嘛)
2.數據結構確實的能看懂,尤其是鏈表
3.一定要有著非常濃厚的興趣,不成魔,不成活
第3點尤其最重要,因為興趣才是王道

假設你已經對上述內容有了一定的了解或者已經是個老手了!想急需的去更深入的研究內核!
那麽我們就開始吧!

1. 你應該了解內核源碼樹

頂層目錄

├── arch            --  體系架構相關代碼,內核支持市面上所有的主流架構以及N多種CPU
├── block           -- 塊設備子系統
├── crypto          -- 加密解密庫函數
├── Documentation   -- 說明文檔
├── drivers         -- 設備驅動
├── firmware        -- 第三方設備固件
├── fs              -- 文件系統子系統(VFS)
├── include         -- 公共頭文件
├── init            -- 啟動初始化子系統(如掛載initrd)
├── ipc             -- 進程通信子系統
├── Kbuild          -- 頂層鏈接文件
├── Kconfig         -- 頂層配置配置
├── kernel          -- 內核核心代碼(基本與架構無關,包括調度子系統)
├── lib             -- 公共LIB庫函數
├── Makefile        -- 頂層編譯文件
├── mm              -- 內存管理子系統
├── net             -- 不包括網絡設備驅動的網絡子系統
├── README          -- 你懂得
├── samples         -- Demo 代碼
├── scripts         -- 編譯腳本以及工具
├── security        -- 模塊安全相關(SELinux)
├── sound           -- 音頻驅動子系統
├── tools           -- 內核輔助工具
├── usr             -- 用戶程序(目前只有一個用於initramfs的cpio打包程序)
└── virt            -- 虛擬化相關
├── REPORTING-BUGS  -- Bug 上報流程
├── MAINTAINERS     -- 主要維護者(向社區致敬)
├── CREDITS         -- 貢獻者(請牢記偉大的程序員)

內核真是太龐大了,目前這個版本的代碼量已經到了幾百萬行之多,那麽問題來了,這麽多的內容我們應該如何取舍?

2. Linux Kernel 核心功能一覽

Linux 核心功能分為五大子系統(進程管理,內存管理,虛擬文件系統,網絡子系統,進程間通信)!
Ps.下面是網上找了一張圖片
技術分享圖片

  1. Process Mangement稱作進程管理or進程調度。主要負責管理CPU資源的平衡調度,搶占,異常入口等的管理。主要為了確保各個進程盡量以公平的方式來對CPU執行調度!Ps.這裏其實就要說到優先級等相關內容!這部分是必須要研究的一部分!
  2. Memory Manager稱作內存管理。主要負責管理內存資源的分配以及配額,確保各個進程任務可以放心去共享使用當前的內存資源。此外,內存管理也會提供虛擬內存機制處理,該機制可以讓進程使用多於系統可用Memory的內存(也就是內存地址轉換),不用的內存會通過文件系統保存在外部非易失存儲器中,需要使用的時候,再取回到內存中。這部分也是必須要研究的一部分!
  3. IPC稱作進程間通信。它主要負責Linux系統中進程之間的通信,這裏跟硬件無關! 這部分無需多說,必須研究!
  4. Network稱作網絡子系統,主要負責管理系統的網絡設備,並實現多種多樣的網絡標準以及提供各種各樣協議的基本協議棧。這部分如果從事網絡領域可以仔細研究(難點也是在於協議棧),這部分可以了先了解!
  5. Virtual File System稱作虛擬文件系統。Linux內核將不同功能的外部設備,例如Disk設備(硬盤、磁盤、NAND Flash、Nor Flash等)、輸入輸出設備、顯示設備等等,抽象為可以通過統一的文件操作接口(open、close、read、write等)來訪問。這部分如果從事存儲就必須要研究啦!它往往是結合塊設備驅動來進行的!
  6. SELinux/AppArmor號稱最傑出的操作系統安全子系統,最早由NSA(美國國家安全局)來領導並研發的一套安全子系統!這部分內容如果暫時可以先了解下!

Ps…對了,還忘了說一個非常非常重要的核心,那就是體系架構,因為我當前是Mips,所以首先的熟悉MIPS架構中的一些最基本的處理方式,並且內核中有很多關於MIPS的匯編以及GUN混合MIPS的偽匯編,都需要去啃啊,瞬間好頭大!深吸一口氣,慢慢來吧!這部分內容作為整體穿插的時候在進行腦補吧!!!!

3.Makefile

好吧,下一節就要進行實戰了,這裏先腦補一下Makefile.
Makefile作為構建內核的引線,穿插在各個目錄中!那麽對它的語法先簡單的了解下!
基本的 make流程 其實是根據文件的時間戳來更新(讀取Makefile) 文件的編譯工作
從一個樣例來說明Makefile.

    main:main.o name.o age.o
           gcc main.o name.o age.o -o main
    main.o:main.c
           gcc -c main.c -o main.o
    name.o:name.c
           gcc -c name.c -o name.o
    age.o:age.c
           gcc -c age.c -o age.o
    clean:
          rm *.o main  

基本格式為: 目標生成文件名:源文件
生成過程(得到結果)
clean 作為方便的清除Makefike生成的編譯文件
看上述的主文件
main.c

    #include <stdio.h>                                                                     
    extern void name();
    extern void age();

    int main()
    {
         name();
         age();

         return 0;
    }       
    name.c
    #include <stdio.h>                                                                     

    void name()
    {
         printf("My name is Xw. \n");
    }

    age.c
    #include <stdio.h>                                                                     

    void age()
    {
         printf("My age is 22........\n");
    }
  • 直接編譯可產生結果。

雜種Shell + Makefile的演變
當我們的可編譯文件越來越多時候,那麽即時可能你少了一個.o文件那也直接導致程序崩潰。
所以這個時候我們的雜種Shell(其實嚴謹的說不是shell相似而已)就有用了。我們大可以用一個變量去代替你的源文件、也可以代替我們的編譯器。如下

     CC=gcc                           //變量代替你的編譯器                                                      
     OBJS=main.o name.o age.o       //源文件
     main:$(OBJS)
             $(CC) $^ -o $@
     main.o:main.c
             $(CC) -c $^ -o $@
     name.o:name.c
             $(CC) -c $^ -o $@
     age.o:age.c
             $(CC) -c $^ -o $@
     clean:
             rm *.o main
  • 沒有出現的<<這些命令以後會用到。分別先介紹一下@ 表示目標文件的完整名稱 如上述main main.o name.o age.o等

main.omain.c表示所有不重復的依賴包名稱以空格隔開如上述main.omain.c分別可以做依賴包、因為依賴和被依賴僅僅是方向不一樣。其實是可以轉化的。當然上述還可以寫成。(CC) -c OBJS?omain.oOBJS?omain.o<表示第一個依賴包名稱

Ps.上述僅僅是Makefile 最基本的使用,在內核裏完全是另外一回事,但是基本語法是一樣的!

*下一節我們就開始內核的Makefile以及其它編譯規則的分析*

全面解析Linux 內核 3.10.x - 如何開始