現狀:第一次讀內核的源代碼(物理內存管理第二次)。

資源:Linux-2.6內核源碼(vscode代碼瀏覽)+《深入Linux內核架構》

癥狀:(1)學習的速度慢。(2)看完一部分代碼後總是覺得零零散散不成系統 。

說明:第一個癥狀的原因是我看代碼的時候喜歡一層一層把輔助函數打開看,不知道這樣對不對。


首先,默認你對C語言已經十分精通,我的「精通」的意思是你能做到對C語言的編譯過程瞭然於心,深刻理解C語言編譯器是如何把文本的C源碼編譯成二進位指令的。如果沒有做到,請自學做到。

其次,默認你對彙編語言有一定了解,熟悉ATT的基本彙編語法,瞭解偽指令和指令的差異,理解「彙編源碼文件是用來生成一段二進位文件塊的操作指示文件」這句話的含義。如果沒有做到,請自學做到。

閱讀Linux內核代碼的準備步驟:

1、讀一下Tanenbaum的《現代操作系統》這本書,理解了4大基本概念:Thread(線程/進程)、VMS(虛擬內存系統)、VFS(虛擬文件系統)、I/O。

2、讀一下ARM或者X86(選一種即可)的Specification,理解了6大CPU機制:寄存器機制、多級緩存機制、分段機制、分頁機制、中斷機制、多核同步機制。

3、選一個版本的內核源碼(例如v3.18.137),選一個CPU架構(例如X86_64)。

4、下載選定版本的內核源碼,並按照選的的CPU架構裁剪源碼(刪掉其他架構的源碼)。

5、配置好編譯流程。

現在你可以閱讀內核代碼了,注意幾個事項:

1、用 https://elixir.bootlin.com/linux/v3.18.137/source 之類輔助普通IDE閱讀內核源碼,有奇效。

2、早期,可以在內核源碼的任意地方,用printk()輸出調試信息,輔助學習;熟了之後,自己寫一個內核模塊,可以通過/proc/kallsyms找到任意內核符號的地址,從而可以隨時讀取任意的內核數據,輔助學習。

3、不要用「一層一層的函數」的視角看待內核源碼,內核是由三類符號組成的:代碼符號(函數)、數據符號(struct定義)、變數符號(具體類型的變數)。你首先要了解的是每一個功能模塊相關的核心符號,例如mmap模塊相關的核心符號有哪些,分別是什麼作用,相互之間什麼關係,最好畫個圖,然後再來看具體每個符號是怎麼實現的(一層一層細讀函數實現)。

Linux源碼博大精深,處處是寶藏,祝福你尋寶順利~

  • - - - - - 以下是補充部分:

填一些操作細節,可以讓入門者少花一些時間

1、快速在mac上做個內核編譯調試環境

2、下邊是一個小項目,可以在1中建立的內核環境中安裝成內核模塊,方便的觀察內核的各類實時數據結構。這對於初學者會有幫助,因為只讀代碼沒用,得配合修改調試和觀察內存數據狀態,纔能有比較好的理解。

crimsonlock/kstudy?

github.com圖標

其實絕大多數人都犯了一個嚴重錯誤:從中間層學起。何為中間層?簡單概括,linux分三層,硬體(驅動)層、內核層、軟體層;如果從中間層學起,無異於隔靴搔癢,前不著村後不著店,不知其所以然也不知其然,學起來特別容易受挫。

而我個人是從底層也就是硬體層學起的,什麼?覺得可怕?說實話,我也是互聯網行業出身,主要在軟體層上磨磨蹭蹭,出於好奇和不甘心,也想深入敵後。

聽起來難,做起來也難!但比上來讀內核源碼,更能把控,更能循序漸進!

我從一個叫6502的cpu學起的,6502是什麼,你可以網上查閱。簡單來說是一個非常古老的但簡約的硬體cpu,最著名的是在Apple II 和Nintendo上使用。這是個很可怕的開始,隨著我學的越來越多,我發現以前的時鐘、boot、內存映射、寄存器簡直是自然而然的事,甚至可以知道怎麼寫好彙編,後來一發不可收拾,我甚至補充了自己電子電路的知識,包括各種門電路,怎麼自己設計pcb,自己設計cpu,是不是很恐怖?但其實,一切都有跡可循,一步一個腳印,而且沒有想像中哪麼可望而不可即。

有很多細節還可以聊,限於時間的原因,以後再說,一些推薦的資料(除非我看過,不然就是不負責):

  1. Linux 內核0.11完全注釋(趙炯) 前兩張足矣,圖個樂,不要深入!
  2. https://github.com/0xAX/linux-insides 關於linux內核的一切,github 兩萬人關注!
  3. 6502介紹 http://wilsonminesco.com/6502primer/65tutor_intro.html
  4. Build a 6502 computer 手把手教你自己創建一臺電腦,需要動手能力!


第一次看就2.6版本了,我是服氣的


首先,你要明確學習的目的是什麼,帶著目標去學習才會有點效果,做內核開發也並不是所有知識都要掌握的。

比如想了解操作系統的功能,從syscall看起,瞭解為什麼設計了這些api,再層層深入。

學習文件系統,就從vfs框架開始,瞭解提供了哪些介面,想想為什麼。

學習內存系統,就從virtual mem開始。等等。

ulk是個比較好的入門書。第一次讀,著眼於大處,別去糾結太細節的實現和演算法,這些往往都是會變化的,然後再挑一個方向深入進去。

目前內核工作主要集中在驅動和功能模塊,需要非常熟悉內存系統,中斷系統,軟中斷以及工作隊列,模塊系統,一部分調度知識。至於別的,都是看手冊而已,難度不高。

如果打算在一個linux base的軟體團隊建立Linux專業類技能,那在我看來就要求所有模塊都需要比較瞭解,要求其實反而更高。


我個人的經驗:

  1. 首先把相關模塊的原理弄清楚(文檔,書籍,博客)

2. 看的過程中畫一下主要數據結構和流程圖,用一些方便的工具比如:筆記本或者processon或者excel之類的工具。

3. 直接一層一層深入函數也是可以的,但是容易陷進去把握不到總體流程。(建議你用excel之類的工具記錄一下函數調用路徑)。

貼兩張我看代碼時做的筆記:


可以看看我們的4分視頻講解,到底應該如何高效閱讀Linux內核源代碼:

4分鐘視頻講解到底該如何高效閱讀Linux內核源代碼linux閱碼場的視頻 · 1450 播放

可以先看看ext2設計與實現文檔,再對著最新的代碼具體看看實現細節,因為ext2比較簡單想讀來說理解起來比較容易,入了門以後需要什麼再深入的看一看。

學習速度的話反而不建議太快,反覆的讀堅持下去總會有質變的。

Linux source code: fs/ext2 (v5.4)

龍蝦星人:ext2文件系統設計與實現(轉)


首先,請先學習操作系統基礎知識,對整個大局有了解;

其次,請先明確自己的興趣點,從興趣點相關模塊開始入手學習

其三,讀代碼和寫代碼混合起來會比較有效

最後,全套內核源碼是很複雜的體系,不可能憑藉單純某個工具給你整理出全體的脈絡

最後的最後是題外話:現在時代不同了,內核不見得能給你帶來好工作了。

然後是廣告:如果對某個代碼細節有興趣討論,可以借用troob.cn這個網站。。就像這樣

http://www.troob.cn/project/linux_kernel_3_16_51/linux-3.16.51/drivers/block/nvme-core.c


推薦閱讀:
相關文章