熱烈祝賀臺州維博網絡的站長論壇隆重上線!(2012-05-28)    熱烈慶祝偉大的祖國60周年生日 點擊進來我們一起為她祝福吧(2009-09-26)    站長論壇禁止發布廣告,一經發現立即刪除。謝謝各位合作!.(2009-08-08)    熱烈祝賀臺州網址導航全面升級,全新版本上線!希望各位一如既往地支持臺州網址導航的發展.(2009-03-28)    臺州站長論壇恭祝各位新年快樂,牛年行大運!(2009-01-24)    臺州Link正式更名為臺州網址導航,專業做以臺州網址為主的網址導航!(2008-05-23)    熱烈祝賀臺州Link資訊改名為中國站長資訊!希望在以后日子里得到大家的大力支持和幫助!(2008-04-10)    熱烈祝賀臺州Link論壇改名為臺州站長論壇!希望大家繼續支持和鼓勵!(2008-04-10)    臺州站長論壇原[社會瑣碎]版塊更名為[生活百科]版塊!(2007-09-05)    特此通知:新臺州站長論壇的數據信息全部升級成功!">特此通知:新臺州站長論壇的數據信息全部升級成功!(2007-09-01)    臺州站長論壇對未通過驗證的會員進行合理的清除,請您諒解(2007-08-30)    臺州網址導航|上網導航誠邀世界各地的網站友情鏈接和友誼聯盟,共同引領網站導航、前進!(2007-08-30)    禁止發廣告之類的帖,已發現立即刪除!(2007-08-30)    希望各位上傳與下載有用資源和最新信息(2007-08-30)    熱烈祝賀臺州站長論壇全面升級成功,全新上線!(2007-08-30)    
便民網址導航,輕松網上沖浪。
臺州維博網絡專業開發網站門戶平臺系統
您當前的位置: 首頁 » Linux內核/嵌入技術 » Linux啟動過程中硬件模塊的加載

Linux啟動過程中硬件模塊的加載

論壇鏈接
  • Linux啟動過程中硬件模塊的加載
  • 發布時間:2010-11-09 16:53:00    瀏覽數:6360    發布者:abcdef133    設置字體【   
前言:我覺得我的文章相對來說都是比較淺顯的。一些初學者可以看看,對于高手來說,如果你們不吝嗇時間的話,希望也能幫我看看,指點一下其中的錯誤。這也是我到這里來和大家交流的目的。

  閱讀Linux內核啟動代碼的直接動力是我想編寫RTL8019AS的網卡驅動程序(2.4.18內核只支持了CS8900A)。既然要寫驅動,我就想知道它是怎么樣被加載的,好奇心驅使我先去搞定這個問題。

  拿到2.4.18的軟件包,一萬多個文件,我不知怎么下手。所幸手頭有這么三件工具助我入門:

  1,一塊移植好linux的開發板,通過它可以看到linux啟動過程打印的消息。

  2, google,網上關于linux的資料真是太多了。!

  3, Windows文件搜索引擎,通過它可以知道在那些文件中打印出那些消息。

  很快,我就找到了linux啟動的總的入口,/arch/arm/boot/compressed/head.s。

  head.s完成的工作主要是底層寄存器、MMU的一些設定以及kernel的解壓縮。匯編文件中調用的C代碼大多位于該目錄下misc.c文件,比如decompress_kernel。

  當然,這部分不是重點,head執行完畢以后就跳到start_kernel(),這才是我們的重點所在,這個函數位于文件/init/main.c中。這個文件是啟動的主線。!

  在start_kernel中,依次執行各個初始話函數,這里具體我沒有看,一直到最后rest_init(),在這個函數里啟動了一個init線程,而主線程自己則進入了IDLE狀態。所以我們關心一下init線程做了什么事情,看文件最后init函數。

  在這個函數里面,先lock_kernel,然后調用do_basic_setup,在這個函數里面又是一堆的初始化,有一個函數要引起我們的注意:do_initcalls?纯此闪耸裁矗海ㄟ@之后的東西在下文文件系統中講解)

  static void __init do_initcalls(void)

  {

  initcall_t *call;

  call = &__initcall_start;

  do {

  (*call)( );

  call++;

  } while (call < &__initcall_end);

  /* Make sure there is no pending stuff from the initcall sequence */

  flush_scheduled_tasks();

  }

  很難相信,我們關心的外圍模塊的驅動就是被這一段程序加載的。怎么回事?我們慢慢來看:

  首先看__initcall_start和__initcall_end,找遍了所有C代碼,沒有它們的定義。后來在vmlinux-armv.lds.in文件中找到了它們:

  __initcall_start = .;

  *(.initcall.init)

  __initcall_end = .;

  這個文件是和link相關的文件,它決定代碼在load環境中的位置,就好比ADS中的scf文件。我們還是先看.initcall.init的含義吧,它在/include/linux/init.h中定義:

  #define __init_call __attribute__ ((unused,__section__ (".initcall.init ")))

  參考GCC說明,這段話的意思就是說所有以__init_call前綴定義的函數在鏈接過程中都放到名字為.initcall.init的段(section)里面。OK,有點味道了,也就是說,如果我們給一個函數冠以__init_call,那么它在編譯鏈接的時候就會放到.initcall.init這個段里面。而上面這段循環所做的事情就很清楚了,它從段的首地址開始,依次執行每一個函數,直到段尾為止。

  這個時候,我們應該在想,那些要注冊的外圍模塊的初始化程序是不是都是定義成__init_call類型的呢?正如我們所料,查看各個模塊我們會發現其初始化函數x會被定義成為module_init(x),在/include/linux/init.h中它定義如下:

  #define module_init(x) __initcall(x);

  #define __initcall(fn) static initcall_t __initcall_##fn __init_call = fn

  這段代碼說module_init(x)等價于__initcall(x),而__initcall(x)表示函數x是靜態的具有__init_call性質的函數(這里名字比較多,容易看亂),因此在鏈接時,它會被放在.initcall.init段中。只要x函數運行起來了,那就可以注冊設備、中斷入口、中斷服務函數了。接下來的事情就好辦了。

  搞清出設備如何被加載以后,我們還需要知道另外一個問題:怎樣把一個模塊的驅動程序加載到內核里面呢?SO簡單,make menuconfig,把對應設備打開。但是能不能再具體一點呢,我們做這么一個改動,怎么映射到編譯&鏈接過程呢。我這個人就是喜歡找麻煩,因此又在網上搜啊搜,而且用了最笨的方法,看看make menuconfig前后那些文件的修改日期發生了變化。最終還是找到了一點,/scripts下的文件是用來支持各種config模式的(當然包括menuconfig),核心代碼在Kconfig中。在每個驅動設備的文件夾下(比如net,mtd)都有一個叫config.in的文件,這些文件定義了我們在menuconfig畫面中看到的目錄結構&選項。

  眼睛看到的畫面總歸都是虛的,這些改動究竟反映到了哪里去了呢?兩個文件:./config和/include/linux/ autoconf.h。我們做完menuconfig以后,所有改動就反映到了這兩個文件中,這兩個文件的內容是一致的。在我們做編譯的過程中,頂層的makefile文件從autoconf.h文件中讀取各項宏定義然后傳遞給子一層的makefile,這些makefile根據宏定義選擇那些.o文件被鏈接進來加到內核中。

  好了,知道這些我就知道怎么給8019添加驅動了,yy一下:

  1,首先要有驅動程序代碼,8019.c

  2,修改net目錄下的config.in文件中添加一項,

  dep_tristate ' RTL8019 support' CONFIG_RTL8019 $CONFIG_ISA

  3,打開menuconfig,將RTL8019 support選擇y,保存推出后autoconf文件中應該

  就有了一個宏定義:#define CONFIG_RTL8019

  4,打開net目錄下的makefile,添加:

  obj-$( CONFIG_RTL8019) += 8019.o

  5,make dep; make zImage;搞定!

  注:在menuconfig中選擇m和y的區別:

  y: 模塊驅動編譯到內核中,啟動時自動加載

  m:模塊會被編譯,但是不會被編譯到內核中,只是生成.o文件,我們可以收集這些.o文件做到linux的文件系統中,然后用insmod實現動態加載。
娛樂休閑專區A 影視預告B 音樂咖啡C 英語階梯D 生活百科
網頁編程專區E AMPZF HTMLG CSSH JSI ASPJ PHPK JSPL MySQLM AJAX
Linux技術區 N 系統管理O 服務器架設P 網絡/硬件Q 編程序開發R 內核/嵌入
管理中心專區S 發布網址T 版主議事U 事務處理
陕西快乐10分玩法 福建十一选五走势 万科a最新股票分析报告 北京pk10彩票官网 排列7几点开奖 甘肃11选五方法技巧 互联网理财平台 福彩网江苏快三app 广西快三遗漏数据 上海时时乐开奖号码走势 云南十一选五开奖