日韩欧美自拍在线观看-欧美精品在线看片一区二区-高清性视频一区二区播放-欧美日韩女优制服另类-国产精品久久久久久av蜜臀-成人在线黄色av网站-肥臀熟妇一区二区三区-亚洲视频在线播放老色-在线成人激情自拍视频

Linux啟動過程中硬件模塊是如何加載的?

出處:互聯(lián)網(wǎng)    發(fā)布于:2011-09-04 12:31:40

  閱讀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)上關(guān)于linux的資料真是太多了!

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

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

  start:

  .type  start,#functiON

  .rept    8

  mov    r0,r0

  .endr

  ……

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

  head執(zhí)行完畢后跳到start_kernel(),這個函數(shù)位于文件/init/main.c中。

  在start_kernel中,依次執(zhí)行各個初始話函數(shù),直到rest_init(),在這個函數(shù)里啟動了一個init線程,而主線程自己則進入了IDLE狀態(tài)。

  在這個函數(shù)里面,先lock_kernel,然后調(diào)用do_basic_setup,在這個函數(shù)里面又是一堆的初始化,有一個函數(shù)要注意:do_initcalls??纯此闪耸裁矗簊tatic 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();}

  我們所關(guān)心的外圍模塊的驅(qū)動被這一段程序加載的原因:

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

  __initcall_start = .;*(。initcall.init)__initcall_end = .;這個文件是和link相關(guān)的文件,它決定代碼在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)里面。如果我們給一個函數(shù)冠以__init_call,那么它在編譯鏈接的時候就會放到。initcall.init這個段里面。

  那么要注冊的外圍模塊的初始化程序是不是都是定義成__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)核里面呢?make menuconfig,把對應設備打開。看看make menuconfig前后哪些文件的修改日期發(fā)生了變化?找到了一點,/scripts下的文件是用來支持各種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)加載。



  

版權(quán)與免責聲明

凡本網(wǎng)注明“出處:維庫電子市場網(wǎng)”的所有作品,版權(quán)均屬于維庫電子市場網(wǎng),轉(zhuǎn)載請必須注明維庫電子市場網(wǎng),http://www.hbjingang.com,違反者本網(wǎng)將追究相關(guān)法律責任。

本網(wǎng)轉(zhuǎn)載并注明自其它出處的作品,目的在于傳遞更多信息,并不代表本網(wǎng)贊同其觀點或證實其內(nèi)容的真實性,不承擔此類作品侵權(quán)行為的直接責任及連帶責任。其他媒體、網(wǎng)站或個人從本網(wǎng)轉(zhuǎn)載時,必須保留本網(wǎng)注明的作品出處,并自負版權(quán)等法律責任。

如涉及作品內(nèi)容、版權(quán)等問題,請在作品發(fā)表之日起一周內(nèi)與本網(wǎng)聯(lián)系,否則視為放棄相關(guān)權(quán)利。

廣告
OEM清單文件: OEM清單文件
*公司名:
*聯(lián)系人:
*手機號碼:
QQ:
有效期:

掃碼下載APP,
一鍵連接廣大的電子世界。

在線人工客服

買家服務:
賣家服務:
技術(shù)客服:

0571-85317607

網(wǎng)站技術(shù)支持

13606545031

客服在線時間周一至周五
9:00-17:30

關(guān)注官方微信號,
第一時間獲取資訊。

建議反饋

聯(lián)系人:

聯(lián)系方式:

按住滑塊,拖拽到最右邊
>>
感謝您向阿庫提出的寶貴意見,您的參與是維庫提升服務的動力!意見一經(jīng)采納,將有感恩紅包奉上哦!