linux四個維度

 linux系統是軟件開發歷史上的一個傳奇。來自全球的個人、公司、團體爲了完成開放和自由的訴求,在一種鬆散但是卻有效的方式下,成功地創建一個偉大的生態系統。無論從軟件的規模和穩定性上面,linux都是首屈一指的。當然這裏說的linux更多的是一個生態,它包括內核、驅動、庫文件、gui、數據庫以及上層應用軟件。linux產生的基因決定了它的應用只能侷限在一個小的範圍內。當然,你可以不服氣地說不是還有android嘛,但是我們要清楚android事實上是一個建立在linux之上的虛擬機,嚴格意義上說和linux的關係不是那麼大。沒有google的推廣和移動終端聯盟的支持,Linux系統本身只能偏安一隅,在特定的領域發揮特定的作用,而不是像windows一樣成爲所有人每天必須要面對的系統軟件。


         當然,說了這麼多,我們真正關心的是自身可以從這個生態圈中獲得些什麼?說得更直白一點就是,我們可以從linux系統上面學到點什麼,它對我們個人的成長和發展有哪些積極的因素。個人覺得,完全可以通過下面四個維度並結合自己的興趣進行選擇和判斷。


    (1)熟練學習linux、配置linux和使用Linux

        2011年有一本書特別火,長期位列在熱銷排行榜上,這本書就是《鳥哥的linux私房菜》。這本書以centos爲例,講了很多的內容,比如說系統安裝、常見配置、軟件更新、特殊命令的用法、服務器的配置等等。整本書的內容很厚,而且內容是一版再版,可見大家對linux的基礎知識是非常渴求的。另外一方面,現在隨着電商和視頻網站的迅速發展,一種稱爲運維工程師的職業開始熱門起來。由於行業的特殊性,某些互聯網公司需要成百上千的服務器統一對客戶進行服務,那麼怎麼樣搭建網站、配置服務器均衡負載、進行遠程控制、正確配置數據庫和統一管理服務器集羣,這些都是運維工程師需要關注的事情。從這個意義上來說,運維工程師的重要性可見一般了。


   (2)利用linux開發應用層軟件

        通俗意義上來說,利用linux開發應用層的軟件和windows上面開發應用軟件沒有什麼不同。可能,在windows上面使用得比較多的就是mfc、gdi、win32這些接口,而在嵌入式上面使用的就比較多種多樣了,什麼qt、minigui、gtk都是可以用來進行開發的。當然,上面說的都是界面程序,很多公司的linux程序是沒有界面的,比如說遊戲公司的linux工程師。相比較而言,他們看中的更多的是linux的穩定性,所以在linux上開發的更多的都是服務器端程序。很多人都有一個誤解,認爲操作系統就一定比應用軟件高級,其實不然。在我看來,office、webkit、samba、mplayer這些軟件的代碼都是在百萬行以上,本身的結構也是相當複雜的。說到應用開發,網上有幾本書,分別是《linux程序設計》、《unix環境高級編程》、《unix網絡編程》,對我們都很有借鑑意義。誠然有些書是基於unix系統的,但是基本的編程接口都是差不多的,相應的代碼在linux跑絕對沒問題。


    (3)利用linux開發驅動

        和其他os系統開發驅動的工作一樣,linux驅動開發也有自己的一整套流程。要想真正地做好驅動,一般來說你需要知道芯片的寄存器特性、電氣原理圖、總線標準,當然熟悉信號測試,通曉定時器、互斥工具、回調機制、位運算、中斷機制、芯片設置、信號時序、地址分配,這些也是少不了的。更極端一點,如果本身創業的公司比較小,驅動開發工程師有的時候還需要自己測試信號、調試boot、焊接芯片,這些都是可能的。所以說,對於真正的芯片企業來說,無論是美資、日資、臺資企業來說,驅動開發工程師的收入都是非常可觀的。特別是現在有了android的推波助瀾,驅動開發工程師的薪酬更是水漲船高。希望在軟件上有所突破的硬件工程師或者是希望對系統本身進行更多瞭解的軟件工程師,都可以將此作爲自己長期發展的一個方向。關於這方面的書很多,《linux driver development》無疑是人氣最旺的一本,但是我想說的是有一本國內朋友寫的書也相當不錯,那就是宋寶華的《Linux設備驅動開發詳解》,質量也相當不錯,朋友們有時間也可以關注一下。

 

        linux驅動其實並不複雜,我們要做的就是在linux統一的驅動框架下實現對外設的統一管理。很多的代碼架構都是現成的,所以我們只要做好模仿、學習、測試和驗證就可以了。比較簡單的代碼就是下面的這一段話,

  1. #include <linux/init.h>  
  2. #include <linux/module.h>  
  3.   
  4. MODULE_LICENSE("GPL");  
  5. MODULE_AUTHOR("feixiaoxing");  
  6. MODULE_DESCRIPTION("This is just a hello module!\n");  
  7.   
  8. static int __init hello_init(void)  
  9. {  
  10.     printk(KERN_EMERG "hello, init\n");  
  11.     return 0;  
  12. }  
  13.   
  14. static void __exit hello_exit(void)  
  15. {  
  16.     printk(KERN_EMERG, "hello, exit\n");  
  17. }  
  18.   
  19. module_init(hello_init);  
  20. module_exit(hello_exit);  

        加載模塊就是輸入insmod hello.ko,卸載模塊就是rmmod hello.ko。在這過程中,我們都可以看到相應的打印內容。當然,朋友們可以一直往裏面加代碼,一步步調試,一步步學習,只要堅持和總結,都是可以學習好linux的驅動代碼的。

        這裏順便把Makefile也寫一下,

  1. ifneq ($(KERNELRELEASE),)  
  2. obj-m := hello.o  
  3.   
  4. else  
  5. PWD  := $(shell pwd)  
  6. KVER := $(shell uname -r)  
  7. KDIR := /lib/modules/$(KVER)/build  
  8. all:  
  9.         $(MAKE) -C $(KDIR) M=$(PWD) modules  
  10. clean:  
  11.         rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions  
  12. endif  

    (4)linux kernel代碼移植、修改和維護

        linux kernel代碼相信是被很多人奉爲經典的,但是linux kernel的代碼很長也很難。一方面,linux代碼存在技巧代碼、彙編代碼,同時部分函數冗長、文件冗長、命名不規範,另外一方面linux的代碼分佈合理、系統流程明顯、相關資料衆多。關鍵是我們自己怎麼從linux kernel中學到東西?是看書呢,還是看代碼呢?是每一行都看呢,還是按照模塊看呢?是掌握主要原理呢,還是看實現技巧呢?是看高版本呢,還是先熟悉低版本呢?下面,我想就自己的經歷談談自己的看法,

 

         a)熟悉的代碼認真看,不熟悉的代碼瞭解一下接口就可以,對於內存管理只要瞭解__get_free_page、kmalloc、vmalloc這幾個函數就可以了;

         b)代碼不要貪多求快,多思考多實踐;

         c)忽視技巧,看中代碼的處理流程和策略的權衡,多多思考爲什麼要這麼設計;

         d)利用module特性查看代碼的執行日誌,代替函數堆棧的功能;

         e)瞭解linux性能的改進方法,瞭解爲什麼有軟中斷、rcu、slab和各種各樣的延時函數;

         f)自己編寫os,實現內存管理、信號量、消息隊列、驅動開發、中斷和線程調度,深入理解os的流程。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章