精品乱码一区内射人妻无码-亚洲中文AⅤ中文字幕在线-免费不卡国产福利在线观看-国产综合无码一区二区色蜜蜜

          您現(xiàn)在的位置:智能制造網(wǎng)>技術中心>Linux啟動過程中硬件模塊的加載

          直播推薦

          更多>

          企業(yè)動態(tài)

          更多>

          推薦展會

          更多>

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

          2009年03月25日 08:33:52人氣:972來源:浙江啟揚智能科技有限公司

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

          前言:我覺得我的文章相對來說都是比較淺顯的。一些初學者可以看看,對于高手來說,如果你們不吝嗇時間的話,希望也能幫我看看,指點一下其中的錯誤。這也是我到這里來和大家交流的目的。

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

           

           

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

           

           

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

           

           

          2,  google,網(wǎng)上關于linux的資料真是太多了?。?!

           

           

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

           

           

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

           

           

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

           

           

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

           

           

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

           

           

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

           

           

                 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();

           

           

           

          }

           

           

           

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

           

           

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

           

           

          __initcall_start = .;

           

           

           

          *(.initcall.init)

           

           

           

          __initcall_end = .;

           

           

           

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

           

           

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

           

           

           

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

           

           

          這個時候,我們應該在想,那些要注冊的外圍模塊的初始化程序是不是都是定義成__init_call類型的呢?正如我們所料,查看各個模塊我們會發(fā)現(xiàn)其初始化函數(shù)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)表示函數(shù)x是靜態(tài)的具有__init_call性質(zhì)的函數(shù)(這里名字比較多,容易看亂),因此在鏈接時,它會被放在.initcall.init段中。只要x函數(shù)運行起來了,那就可以注冊設備、中斷入口、中斷服務函數(shù)了。接下來的事情就好辦了。

           

           

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

           

           

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

           

           

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

           

           

          1,首先要有驅(qū)動程序代碼,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的區(qū)別:

           

           

                        y: 模塊驅(qū)動編譯到內(nèi)核中,啟動時自動加載

           

           

                        m:模塊會被編譯,但是不會被編譯到內(nèi)核中,只是生成.o文件,我們可以收集這些.o文件做到linux的文件系統(tǒng)中,然后用insmod實現(xiàn)動態(tài)加載。

           

           

           

           

           

           

           

           

           

           

           

           

           

           

           

           

           

           

           

           

           

          全年征稿/資訊合作 聯(lián)系郵箱:1271141964@qq.com

          免責聲明

          • 凡本網(wǎng)注明"來源:智能制造網(wǎng)"的所有作品,版權均屬于智能制造網(wǎng),轉(zhuǎn)載請必須注明智能制造網(wǎng),http://www.tzhjjxc.com。違反者本網(wǎng)將追究相關法律責任。
          • 企業(yè)發(fā)布的公司新聞、技術文章、資料下載等內(nèi)容,如涉及侵權、違規(guī)遭投訴的,一律由發(fā)布企業(yè)自行承擔責任,本網(wǎng)有權刪除內(nèi)容并追溯責任。
          • 本網(wǎng)轉(zhuǎn)載并注明自其它來源的作品,目的在于傳遞更多信息,并不代表本網(wǎng)贊同其觀點或證實其內(nèi)容的真實性,不承擔此類作品侵權行為的直接責任及連帶責任。其他媒體、網(wǎng)站或個人從本網(wǎng)轉(zhuǎn)載時,必須保留本網(wǎng)注明的作品來源,并自負版權等法律責任。
          • 如涉及作品內(nèi)容、版權等問題,請在作品發(fā)表之日起一周內(nèi)與本網(wǎng)聯(lián)系,否則視為放棄相關權利。

          <
          更多 >

          工控網(wǎng)機器人儀器儀表物聯(lián)網(wǎng)3D打印工業(yè)軟件金屬加工機械包裝機械印刷機械農(nóng)業(yè)機械食品加工設備制藥設備倉儲物流環(huán)保設備造紙機械工程機械紡織機械化工設備電子加工設備水泥設備海洋水利裝備礦冶設備新能源設備服裝機械印染機械制鞋機械玻璃機械陶瓷設備橡塑設備船舶設備電子元器件電氣設備


          我要投稿
          • 投稿請發(fā)送郵件至:(郵件標題請備注“投稿”)1271141964.qq.com
          • 聯(lián)系電話0571-89719789
          工業(yè)4.0時代智能制造領域“互聯(lián)網(wǎng)+”服務平臺
          智能制造網(wǎng)APP

          功能豐富 實時交流

          智能制造網(wǎng)小程序

          訂閱獲取更多服務

          微信公眾號

          關注我們

          抖音

          智能制造網(wǎng)

          抖音號:gkzhan

          打開抖音 搜索頁掃一掃

          視頻號

          智能制造網(wǎng)

          公眾號:智能制造網(wǎng)

          打開微信掃碼關注視頻號

          快手

          智能制造網(wǎng)

          快手ID:gkzhan2006

          打開快手 掃一掃關注
          意見反饋
          關閉
          企業(yè)未開通此功能
          詳詢客服 : 0571-87858618