Linux0.01內核基本上分析完了,高版本的內核也看了一點。有一點心得與大家分享 一下吧!這裡我並不打算說具體的技術方面的東西,而是針對讀內核的方法,談談自己 的一點感受。 我前段時間主要看的是0.01版本的內核。Linux0.01是Linux的"祖師爺"Linus完成的最早 的一個Linux版本,其內核編譯後僅僅只有512K,麻雀雖小,五髒俱全,0.01包括了從軟 盤啟動、文件系統、控制台管理的操作系統完整功能,並提供了不少標准的用戶接口, 具體有kernel, boot, fs, init,mm等幾個部分,沒有網絡部分。 為什麼選擇Linux0.01?各位大蝦一看到0.01肯定直搖頭:哎呀,都什麼時代的東東 了,有看的必要麼?筆者當初選擇0.01並沒有太多的想法,只是Tm-linux小組剛開始選 擇的是0.01,於是就開始讀吧,現在仔細想想,讀Linux0.01對於初學者來說可能更容易 上手些。可能有下面的幾個好處吧 1)0.01的代碼量較小。很多同學都曾有成為Linux高手的欲望,也曾抱回若干磚頭書,但 Linux的發展何其之快,而coder又是黑客型高手,往往堅持不了多長時間而中途放棄! 2)0.01的代碼簡單而精簡(這個簡單當然是相對於後續版本而言的)。實際上0.01完成 的就是一個操作系統的最初的要求,包括啟動,進程調度,內存管理等,而這些往往與 硬件結合,在看高版本的內核時往往還沒有接觸到這些硬件知識,層層下調已經把你搞 糊塗了。 3)從低版本看更能看到技術進步的源動力,比如0.01的內核很小,其啟動代碼可以只放 在一個扇區內,而後續版本的內核較大,無法放入一個扇區內,於是壓縮核心的裝入方 法誕生了。再如內存管理,0.01的內存管理比較簡單,內存的申請釋放直接通過使用前申請, 使用後釋放,但考慮以後的版本功能復雜,如何解決可能的"外碎片"問題,如何解決內存不足的問題,於是對後續版本采用的"伙伴算法" ,slab技術,頁面守護進程有更好的理解。 我說上面的這一些並非是為0.01做廣告啦,而是提醒一下讀內核可能遇到的問題: 比如說層次復雜難以理清,代碼眾多不知主次,哪些是操作系統必需的,那些是為提高系 統性能的等。 看內核的目的是什麼,這是每個看內核的人都需要問問自己的問題。 我想對於大多數初看內核的人來說,最重要的是解決從操作系統原理到一個實際操 作 系統的過渡,簡單一點說是操作系統到底是怎麼跑起來的。操作系統原理大家都學了,但 一個操作系統到底是怎麼啟動的,所謂的保護模式到底是怎麼一回事,進程調度和切換 到底是怎麼進行的,一個文件系統具體應該怎樣,可能很多還是模糊的。通過看Linux內 核,這些問題可以得到清晰的解答。 當然,一個有強大生命力的操作系統決不會僅僅滿足於能跑起來,她采用的眾多先進的 技術使得她有出色的性能,對於以後的工程設計、編程還有類Unix下的系統開發會有很 多幫助。 鑒於Linux的強大技術實力,在很多領域都會遇到跟其采用技術相關的,如嵌入式領域, 網絡接口等等。理解了內核,當然在以後的開發中可以事半功倍。 我當初讀內核的目的比較簡單,我就是想看看Linux是怎麼跑起來的,為什麼多個進程可 以互不干擾的運行。 我讀代碼的工具是用的source insight,可惜不能自動識別匯編.s文件,而0.01匯編文 件不少。哦,講了這麼多,還沒進入主題:我的體會心得啦 從哪部分開始讀,一般讀內核都建議從boot部分開始讀,這樣循序漸進,而且一般啟動 部分似乎最神秘,最能滿足好奇心啦!不過我是從memory部分開始讀的,因為對邏輯地 址到物理地址的轉換一直很模糊。從你感興趣的地方開始讀,在以後比較容易堅持。在讀內核的方法上,我建議"先橫後縱"。 在讀內核的方法上,我建議"先橫後縱"。 SoUCe insight的好處就是你點上某個函數,能自動顯示該函數的定義,這樣比較方便的 跳入察看。對於剛開始看內核的人,我並不太建議一開始用這種方法。因為函數層層嵌 套,等你下到最底層,早已忘了當初的調用的功能,建議只跳一層看看調用函數的注解 或者簡單看看函數代碼猜測功能,做一些記號。 我個人覺得,操作系同比較重要的是數據結構和算法,算法固然在程序中體現,而數據結 構需要查看相關的頭文件及相關的文件才能了解。所以剛開始時我還是采用一個文件一 個文件的讀,即所謂的"橫",因為一個文件中的安排總是對特定的數據結構的一些操作 ,你有更多的機會去理解各個主要數據結構的功能,包括結構中各個子項的含義。當然 不要忘了寫注釋啦(雖然現在的理解可能並不准確)。 在一個模塊,如FS模塊的各個文件都讀完之後,就采用了所謂的"縱"了,你可以選擇一 個比較重要的函數入手,進行層層跳入(或若干層)以領會各個數據結構間的有機關系 。如fs模塊涉及的主要數據結構有:超級塊,節點索引塊,數據索引塊,高速緩沖塊, 文件等,在單獨理解各個相關文件後,可以從do_execve入手,看一個文件從輸入文件參 數到最後執行的主要步驟,進而理解VFS和具體fs之間的接口。 在每一個主要模塊讀完之後,最後自己寫一份總結(書面總結啦),看看自己對這個模 塊的把握。因為讀代碼往往是比較細致的,可能專注於讀懂代碼本身而忽略了模塊的功 能和組織形式。這點我認為比較重要,所謂"牛吃草要反刍回味",讀代碼也許要在看完 之後進行總結,這樣才能上升一個層次,真正理解其方法和結構的精妙之處。 最後,談談看Linux內核需要的一些基礎吧 1) Intel386硬件知識,比如各寄存器,TSS,段描述表(IDT,GDT,LDT)等,段頁轉換 機制等(高版本的Linux支持其他硬件體系,但對intelx86的比較熟一些吧) 2) 匯編指令,尤其是AT&T語法及其遷入式匯編,當初我初次看到諸如 代碼: __asm__("std ; repne ; scasw\n\t" "jne 1f\n\t" "movw $1,2(%%edi)\n\t" "movw $1,2(%%edi)\n\t" "sall $12,%%ecx\n\t" "movl %%ecx,%%edx\n\t" "addl %2,%%edx\n\t" "movl $1024,%%ecx\n\t" "leal 4092(%%edx),%%edi\n\t" "rep ; stosl\n\t" "movl %%edx,%%eax\n" "1:" :"=a" (__res) :"0" (0),"i" (LOW_MEM),"c" (PAGING_PAGES), "D" (mem_map+PAGING_PAGES-1) :"di","cx","dx"); 這樣的一條匯編語句感到頭腦發脹,不過了解其格式後,多看就習慣了。 3) 操作系統的基本知識,對於操作系統的一般理解,這個大家都有吧! 4) 一本或幾本Linux內核的參考書,有參考書總要好得多,畢竟很多數據結構不用自己 去猜,我在讀0。01感覺有很大不同,很多地方只能猜,不過還是有用的。至於Linux內 核的書已經很多了,到都樂去看看就知道了 5) 恆心+毅力:這是最重要的一點,初始的興趣往往會被遇到的困難一掃而光,再加上 其他雜七雜八的事情,堅持確實很困難。當初Tm-linux組剛開始參加內核分析的人不下 幾十,但堅持到底的也就寥寥數人(這只是0.01哦) 6) 跟別人多多交流,畢竟個人能力有限,通過交流,可以增進知識,我很鼓勵書面的 交流,雖然可能需要花費一些時間來寫,因為書面的東西以後可查,而書面的跟別人交 流總希望正確一點,少犯錯誤啦。這一點西安交大做得比較好,組織了Linux內核論壇, 隔一段時間聚會交流一次,每次有一主題,先有人主講,然後大家互相討論。 這些你有些沒有嗎,那麼恭喜你啦,因為通過讀內核你就可以增加這方面的知識和經驗 了。 讀內核也不是最終目的,對自己在嵌入式系統的開發,或Linux的"運用自如",或者實現 自己的操作系統,那才是"劍出鞘時"! 估計成電讀Linux內核的人不少,只是大家交流比較少,我想交流還是很重要的,雖然牛 人從來都不是問出來的,但具體問題通過交流可以增加理解,提高認識。很願意也鼓勵 大家通過各種方式交流,雖然我不是大牛(也不是小牛啦J),很願意通過bbs,Email, 或其他方式進行交流。 羅嗦了這麼多,希望自己的一點見解能對大家有所啟發,也希望成電湧現更多的Linux牛人啦!