新聞中心

        EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 關(guān)于嵌入式設(shè)備上的Linux 系統(tǒng)開(kāi)發(fā)

        關(guān)于嵌入式設(shè)備上的Linux 系統(tǒng)開(kāi)發(fā)

        作者: 時(shí)間:2012-08-28 來(lái)源:網(wǎng)絡(luò) 收藏

        根據(jù)可用的資源和引導(dǎo)裝載程序的功能,內(nèi)核可以編譯成 vmlinux、Image 或 zImage。vmlinux 和 zImage 之間的主要區(qū)別在于 vmlinux是實(shí)際的(未壓縮的)可執(zhí)行文件,而 zImage是或多或少包含相同信息的自解壓壓縮文件 D 只是壓縮它以處理(通常是 Intel 強(qiáng)制的)640 KB 引導(dǎo)時(shí)間的限制。有關(guān)所有這些的權(quán)威性解釋,請(qǐng)參閱 Magazine的文章“Kernel Configuration: dealing with the unexpected”(請(qǐng)參閱 參考資料)。

        內(nèi)核鏈接和裝入

        一旦為目標(biāo)編譯了內(nèi)核后,通過(guò)使用引導(dǎo)裝載程序(它已經(jīng)被裝入到目標(biāo)的閃存中),內(nèi)核就被裝入到目標(biāo)的內(nèi)存(在 DRAM 中或者在閃存中)。通過(guò)使用串行、USB 或以太網(wǎng)端口,引導(dǎo)裝載程序與主機(jī)通信以將內(nèi)核傳送到目標(biāo)的閃存或 DRAM 中。在將內(nèi)核完全裝入目標(biāo)后,引導(dǎo)裝載程序?qū)⒖刂苽鬟f給裝入內(nèi)核的地址。

        內(nèi)核可執(zhí)行文件由許多鏈接在一起的對(duì)象文件組成。對(duì)象文件有許多節(jié),如文本、數(shù)據(jù)、init 數(shù)據(jù)、bass 等等。這些對(duì)象文件都是由一個(gè)稱為 鏈接器腳本的文件鏈接并裝入的。這個(gè)鏈接器腳本的功能是將輸入對(duì)象文件的各節(jié)映射到輸出文件中;換句話說(shuō),它將所有輸入對(duì)象文件都鏈接到單一的可執(zhí)行文件中,將該可執(zhí)行文件的各節(jié)裝入到指定地址處。 vmlinux.lds是存在于 arch// 目錄中的內(nèi)核鏈接器腳本,它負(fù)責(zé)鏈接內(nèi)核的各個(gè)節(jié)并將它們裝入內(nèi)存中特定偏移量處。典型的 vmlinux.lds 看起來(lái)象這樣:

        清單 2. 典型的 vmlinux.lds 文件

        output_ARCH() /* includes architecture type */

        ENTRY(stext) /* stext is the kernel entry point */

        SECTIONS /* SECTIONS command describes the layout

        of the output file */

        {

        . = TEXTADDR; /* TEXTADDR is LMA for the kernel */

        .init : { /* Init code and data*/

        _stext = .; /* First section is stext followed

        by __init data section */

        __init_begin = .;

        *(.text.init)

        __init_end = .;

        }

        .text : { /* Real text segment follows __init_data section */

        _text = .;

        *(.text)

        _etext = .; /* End of text section*/

        }

        .data :{

        _data=.; /* Data section comes after text section */

        *(.data)

        _edata=.;

        } /* Data section ends here */

        .bss : { /* BSS section follows symbol table section */

        __bss_start = .;

        *(.bss)

        _end = . ; /* BSS section ends here */

        }

        }

        LMA 是裝入模塊地址;它表示將要裝入內(nèi)核的目標(biāo)虛擬內(nèi)存中的地址。 TEXTADDR 是內(nèi)核的虛擬起始地址,并且在 arch// 下的 Makefile 中指定它的值。這個(gè)地址必須與引導(dǎo)裝載程序使用的地址相匹配。

        一旦引導(dǎo)裝載程序?qū)?nèi)核復(fù)制到閃存或 DRAM 中,內(nèi)核就被重新定位到 TEXTADDR — 它通常在 DRAM 中。然后,引導(dǎo)裝載程序?qū)⒖刂妻D(zhuǎn)給這個(gè)地址,以便內(nèi)核能開(kāi)始執(zhí)行。

        參數(shù)傳遞和內(nèi)核引導(dǎo)

        stext 是內(nèi)核入口點(diǎn),這意味著在內(nèi)核引導(dǎo)時(shí)將首先執(zhí)行這一節(jié)下的代碼。它通常用匯編語(yǔ)言編寫(xiě),并且通常它在 arch// 內(nèi)核目錄下。這個(gè)代碼設(shè)置內(nèi)核頁(yè)面目錄、創(chuàng)建身份內(nèi)核映射、標(biāo)識(shí)體系結(jié)構(gòu)和處理器以及執(zhí)行分支 start_kernel (初始化系統(tǒng)的主例程)。

        start_kernel 調(diào)用 setup_arch 作為執(zhí)行的第一步,在其中完成特定于體系結(jié)構(gòu)的設(shè)置。這包括初始化硬件寄存器、標(biāo)識(shí)根和系統(tǒng)中可用的 DRAM 和閃存的數(shù)量、指定系統(tǒng)中可用頁(yè)面的數(shù)目、文件系統(tǒng)大小等等。所有這些信息都以參數(shù)形式從引導(dǎo)裝載程序傳遞到內(nèi)核。

        將參數(shù)從引導(dǎo)裝載程序傳遞到內(nèi)核有兩種方法:parameter_structure 和標(biāo)記列表。在這兩種方法中,不贊成使用參數(shù)結(jié)構(gòu),因?yàn)樗鼜?qiáng)加了限制:指定在內(nèi)存中,每個(gè)參數(shù)必須位于 param_struct 中的特定偏移量處。最新的內(nèi)核期望參數(shù)作為標(biāo)記列表的格式來(lái)傳遞,并將參數(shù)轉(zhuǎn)化為已標(biāo)記格式。 param_struct 定義在 include/asm/setup.h 中。它的一些重要字段是:

        清單 3. 樣本參數(shù)結(jié)構(gòu)

        struct param_struct {

        unsigned long page_size; /* 0: Size of the page */

        unsigned long nr_pages; /* 4: Number of pages in the System */

        unsigned long ramdisk /* 8: ramdisk size */

        unsigned long rootdev; /* 16: number representing the root device */

        unsigned long initrd_start; /* 64: starting address of initial ramdisk */

        /* This can be either in flash/dram */

        unsigned long initrd_size; /* 68: size of initial ramdisk */

        }

        請(qǐng)注意:這些數(shù)表示定義字段的參數(shù)結(jié)構(gòu)中的偏移量。這意味著如果引導(dǎo)裝載程序?qū)?shù)結(jié)構(gòu)放置在地址 0xc0000100,那么 rootdev 參數(shù)將放置在 0xc0000100 + 16,initrd_start 將放置在 0xc0000100 + 64 等等 D 否則,內(nèi)核將在解釋正確的參數(shù)時(shí)遇到困難。

        正如上面提到的,因?yàn)閺囊龑?dǎo)裝載程序到內(nèi)核的參數(shù)傳遞會(huì)有一些約束條件,所以大多數(shù) 2.4.x 系列內(nèi)核期望參數(shù)以已標(biāo)記的列表格式傳遞。在已標(biāo)記的列表中,每個(gè)標(biāo)記由標(biāo)識(shí)被傳遞參數(shù)的 tag_header 以及其后的參數(shù)值組成。標(biāo)記列表中標(biāo)記的常規(guī)格式可以如下所示:

        清單 4. 樣本標(biāo)記格式。內(nèi)核通過(guò) 頭來(lái)標(biāo)識(shí)每個(gè)標(biāo)記。

        #define

        struct {

        u32 ;

        u32 ;

        };

        /* Example tag for passing memory information */

        #define ATAG_MEM 0x54410002 /* Magic number */

        struct tag_mem32 {

        u32 size; /* size of memory */

        u32 start; /* physical start address of memory*/

        linux操作系統(tǒng)文章專題:linux操作系統(tǒng)詳解(linux不再難懂)


        評(píng)論


        相關(guān)推薦

        技術(shù)專區(qū)

        關(guān)閉
        主站蜘蛛池模板: 马边| 泾阳县| 平凉市| 都匀市| 会同县| 正蓝旗| 巴林右旗| 伊金霍洛旗| 兴文县| 来宾市| 峡江县| 黄骅市| 眉山市| 龙海市| 教育| 宁陵县| 邓州市| 科技| 宣武区| 河北区| 亳州市| 蓬溪县| 丰宁| 土默特左旗| 阳新县| 弥勒县| 葵青区| 静乐县| 土默特右旗| 铜鼓县| 章丘市| 揭西县| 金堂县| 太白县| 华坪县| 济源市| 临汾市| 彝良县| 万安县| 板桥市| 江油市|