我想學習x86下的linux內核,該怎麼起步?
x86的彙編懂的,c語言也學過,數電模電也懂的。用過一年的arch,arch的wiki很強大, 會編譯linux內核,但也只只限於此,我想學習 內核源碼
LZ自己會編程更新內核,想必對Linux的使用已經很熟悉了。
至於如何學習內核及編程,我的經驗非常有限,就目前我入門情況來聊聊。不對的地方,願給予指正。
鑒於LZ會x86編程,覺得可以從內核的引導啟動開始:
1.不防從引導程序(bootloader)開始,可以選擇u-boot,熟悉u-boot啟動代碼,比如初始化內存、啟動的彙編代碼是如何跳轉至C程序的、bootloader引導Linux有哪些要求(基於CPU架構不同而不同,比如ARM引導Linux可參考《Booting ARM Linux》http://www.simtec.co.uk/products/SWLINUX/files/booting_article.html)、啟動後是如何傳遞參數給Linux內核的、;2.bootloader將內核映像載入物理內存後,壓縮的內核映像是如何自解壓、head.S文件中對MMU操作、單/多核是如何跑起來的、start_kernel;
btw.內核引導啟動這個過程建議結合一些操作系統的理論知識一起熟悉,比如MMU頁表的建立,若不熟悉對應CPU架構下的MMU,即使懂彙編但代碼看起來可能比較吃力。熟悉內核的引導過程,個人覺得將大學時學的操作系統理論知識與實踐相結合起來了,好多上學時模糊的概念一下清晰了許多。
接下來再來說下內核編程:
1.make menuconfig等配置內核,構建及更新內核(這個LZ可能很熟練了);2.熟悉內核Makefile文件;3.從Hello World開始學習模塊編程,熟悉file_operations嘗試編程簡單的驅動;4.掌握(熟悉使用、區別)內核提供競爭方面的API,spinlock/semaphore/rw_semaphore/completion/rw_lock/mutex,以及RCU等;5.內核態下動態內存API,get_free_pages/kmalloc/vmalloc等(關於內存管理這塊可暫時先了解介面的使用,後續有精力再去熟悉Linux內存管理,裡面太多東西太複雜了,呵呵,我也是略知皮毛);6.內核線程的創建,內核與用戶進程的通信方式;7.網路方面可以先從Socket的實現慢慢熟悉,比如recv系統調用是如何經過傳輸層、網路層把鏈路層的數據包一層一層傳回應用程序的;
8.網路驅動的編寫等;..................需要些時間和耐心,堅持。入門者觀點,但願有所幫助,希望樓下有經驗人士分享~安裝Gentoo或LFS對於熟悉Linux系統很有幫助。
對於內核代碼,我不建議上來就看書。內核代碼很龐大、很繁雜,但無非也就是C ASM,仔仔細細的一行行閱讀,對於鍛煉代碼閱讀能力很有幫助。隨便挑一個感興趣的部分入手就好了。只有「你清楚某些代碼做了什麼,但是不清楚為什麼這麼做」的情況下,才有必要看書尋找答案。以上是一點個人經驗之談。補充一點看法,我不太贊成大而全的學習方式,妄圖將內核一口吞下是不現實的,也沒這個必要。因為現在的內核也不是一個人寫的,追求大而全很容易陷入到內核繁雜的內容中失去信心,或是囫圇吞棗的自以為圓滿,但遇到實際的開發時對細節把握的不夠牢靠,BUG頻出。
我個人認為,學習內核代碼最重要的是培養閱讀代碼的能力,具備了快速的閱讀代碼能力,需要了解哪部份內容的時候再去閱讀就好了。
以我個人經驗來說一下吧。ls已經有了很多的闡述,我也是強烈建議先從一塊做起,當然這一塊可以包括:網路、文件系統、內存管理以及進程調度等等,或者是要更加詳細的小的模塊。這就看lz的興趣所在了。找准方向之後就需要開始動手,最好是先讀一遍操作系統概念中相關部分的理論知識,這樣可以讓你事半功倍,進而加入郵件列表,這部分內核開發者列表、bug列表以及用戶討論列表,看其他人是如何提patch,如何review別人的代碼等等。發現其中比較牛的活躍的人,查找他們的信息,找到並訂閱他們的博客。最後一項準備工作就是選擇一個合適的工具,source insight或是vim+ctags,這個看你的興趣了。內核中最常見的編寫方式應該是狀態機的不同切換,以及各種ioctl,還有就是多線程等等,你要抓住這幾點,然後分別分析,與一般的應用軟體還是不一樣的。最最後,經常看一些bug list,看看哪些是可以fix的,如果可以的話,那就努力去改,如果不可以的話,持續關注,努力去改。通過改bug可以更加有目的性的理解代碼。
模電應該是用不到,想當年我掛的那叫一個悲慘。數電什麼的,也就定時器和時間管理時用的多些,理解jiffies什麼的就夠了。搞個Gentoo的想法不錯,至少讓你自己去配置一下能消除對內核的恐懼心理。當然也可能死活配置不好徹底嚇退。其實按照wiki跟著做應該是不難,感覺不適應的話就換arch。內核的配置選項非常多,推薦自己親手配置。也可以用之前系統的.config文件。
自己配置內核只是第一步,這只是使用者。談不上學習內核。必須要看代碼。linux內核透明性還是很高的,只是入門門檻太高。要想入門,至少認真看半個月的源代碼。耐心看,先看內存管理部分吧。
Ps:內核里的彙編代碼不是很多,而且都是混合編碼,c語言和彙編一起的,以前沒接觸過還是會暈,不過了解了基本規則就好了。我就正在看內核,但是我沒有裝過Gentoo,也沒有弄過LFS,我平常用Arch。
內核源碼很多,雖然是分門別類放好,但是看著也會暈~建議先學習基本的原理,這個可以看看一些內核開發者寫的書,比如 http://book.douban.com/subject/6097773/,這本書基本上講原理,沒有很多代碼。然後可以看詳細一些的,原理和代碼相結合的,比如這個http://book.douban.com/subject/4843567/。記得要在看得過程中理清楚內核主要數據結構和主要子系統之間的關係。當你能夠把數據結構理清後,你會發現看源代碼其實不是很費勁的~可以畫一些圖來輔助~
內核代碼量很大,基本上是沒有可能一行一行看的= =要抓住主要的,拋卻一些次要的,至於什麼是主要、什麼是次要就要你自己去發現了~如果你只是要了解原理的話,看那兩本書,能完全理解書中的內容應該差不多了。如果你很想給Linux內核貢獻代碼,那我建議你從一個比較小的子系統開始~最好有一點操作系統的知識再看內核哦~如果決定看一定要堅持下來哦~
另外給你一篇文章:http://wenku.baidu.com/view/1c7411e59b89680203d825ea.html
直接看代碼吧,如果決定學習了,可以像我一樣看看這個,對理解內核的調用流很有幫助,同時鍛煉自己的動手能力。GitHub - vonnyfly/kernel_visualization: Automaticly draw callgraphs for Linux/Solaris/FreeBSD kernel functions
推薦閱讀: