日韩床上生活一级视频|能看毛片的操逼网站|色悠悠网站在线观看视频|国产免费观看A淫色免费|国产av久久久久久久|免费A级视频美女网站黄|国产毛片av日韩小黄片|热久久免费国产视频|中文字幕无码色色|成人在线视频99久久久

機(jī)電之家資源網(wǎng)
單片機(jī)首頁(yè)|單片機(jī)基礎(chǔ)|單片機(jī)應(yīng)用|單片機(jī)開(kāi)發(fā)|單片機(jī)文案|軟件資料下載|音響制作|電路圖下載 |嵌入式開(kāi)發(fā)
培訓(xùn)信息
贊助商
深入嵌入式系統(tǒng)的 BootLoader
深入嵌入式系統(tǒng)的 BootLoader
 更新時(shí)間:2008-8-18 14:58:37  點(diǎn)擊數(shù):112
【字體: 字體顏色
  • 內(nèi)核映像所占用的內(nèi)存范圍;
  • 根文件系統(tǒng)所占用的內(nèi)存范圍。
  •     在規(guī)劃內(nèi)存占用的布局時(shí),主要考慮基地址和映像的大小兩個(gè)方面。
        對(duì)于內(nèi)核映像,一般將其拷貝到從(MEM_START+0x8000) 這個(gè)基地址開(kāi)始的大約1MB大小的內(nèi)存范圍內(nèi)(嵌入式 Linux 的內(nèi)核一般都不超過(guò) 1MB)。為什么要把從 MEM_START 到MEM_START+0x8000 這段 32KB 大小的內(nèi)存空出來(lái)呢?這是因?yàn)?Linux 內(nèi)核要在這段內(nèi)存中放置一些全局?jǐn)?shù)據(jù)結(jié)構(gòu),如:?jiǎn)?dòng)參數(shù)和內(nèi)核頁(yè)表等信息。
        而對(duì)于根文件系統(tǒng)映像,則一般將其拷貝到 MEM_START+0x0010,0000 開(kāi)始的地方。如果用 Ramdisk 作為根文件系統(tǒng)映像,則其解壓后的大小一般是1MB。

    (2)從 Flash 上拷貝
        由于像 ARM 這樣的嵌入式 CPU 通常都是在統(tǒng)一的內(nèi)存地址空間中尋址 Flash 等固態(tài)存儲(chǔ)設(shè)備的,因此從 Flash 上讀取數(shù)據(jù)與從 RAM 單元中讀取數(shù)據(jù)并沒(méi)有什么不同。用一個(gè)簡(jiǎn)單的循環(huán)就可以完成從 Flash 設(shè)備上拷貝映像的工作:
    while(count) {
    *dest++ = *src++; /* they are all aligned with word boundary */
    count -= 4; /* byte number */
    };

    3.2.4 設(shè)置內(nèi)核的啟動(dòng)參數(shù)
        應(yīng)該說(shuō),在將內(nèi)核映像和根文件系統(tǒng)映像拷貝到 RAM 空間中后,就可以準(zhǔn)備啟動(dòng) Linux 內(nèi)核了。
        但是在調(diào)用內(nèi)核之前,應(yīng)該作一步準(zhǔn)備工作,即:設(shè)置 Linux 內(nèi)核的啟動(dòng)參數(shù)。
        Linux 2.4.x 以后的內(nèi)核都期望以標(biāo)記列表(tagged list)的形式來(lái)傳遞啟動(dòng)參數(shù)。啟動(dòng)參數(shù)標(biāo)記列表以標(biāo)記 ATAG_CORE 開(kāi)始,以標(biāo)記 ATAG_NONE 結(jié)束。每個(gè)標(biāo)記由標(biāo)識(shí)被傳遞參數(shù)的 tag_header 結(jié)構(gòu)以及隨后的參數(shù)值數(shù)據(jù)結(jié)構(gòu)來(lái)組成。

    數(shù)據(jù)結(jié)構(gòu) tag 和 tag_ header 定義在 Linux 內(nèi)核源碼的include/asm/setup.h 頭文件中:
    /* The list ends with an ATAG_NONE node. */
    #define ATAG_NONE 0x00000000

    struct tag_header {
        u32 size; /* 注意,這里size是字?jǐn)?shù)為單位的 */
        u32 tag;
    };
    ……
    struct tag {
        struct tag_header hdr;
        union {
            struct tag_core core;
            struct tag_mem32 mem;
            struct tag_videotext videotext;
            struct tag_ramdisk ramdisk;
            struct tag_initrd initrd;
            struct tag_serialnr serialnr;
            struct tag_revision revision;
            struct tag_videolfb videolfb;
            struct tag_cmdline cmdline;
            /*
            * Acorn specific
            */
        struct tag_acorn acorn;
        /*
        * DC21285 specific
        */
        struct tag_memclk memclk;
    } u;
    };
    在嵌入式 Linux 系統(tǒng)中,通常需要由 Boot Loader 設(shè)置的常見(jiàn)啟動(dòng)參數(shù)有:ATAG_CORE、ATAG_MEM、ATAG_CMDLINE、ATAG_RAMDISK、ATAG_INITRD等。
    比如,設(shè)置 ATAG_CORE 的代碼如下:
    params = (struct tag *)BOOT_PARAMS;
    params->hdr.tag = ATAG_CORE;
    params->hdr.size = tag_size(tag_core);
    params->u.core.flags = 0;
    params->u.core.pagesize = 0;
    params->u.core.rootdev = 0;
    params = tag_next(params);
    其中,BOOT_PARAMS 表示內(nèi)核啟動(dòng)參數(shù)在內(nèi)存中的起始基地址,指針 params 是一個(gè) struct tag 類(lèi)型的指針。
    宏 tag_next() 將以指向當(dāng)前標(biāo)記的指針為參數(shù),計(jì)算緊臨當(dāng)前標(biāo)記的下一個(gè)標(biāo)記的起始地址。

    注意,內(nèi)核的根文件系統(tǒng)所在的設(shè)備ID就是在這里設(shè)置的。

    下面是設(shè)置內(nèi)存映射情況的示例代碼:
    for(i = 0; i < NUM_MEM_AREAS; i++) {
        if(memory_map[i].used) {
            params->hdr.tag = ATAG_MEM;
            params->hdr.size = tag_size(tag_mem32);
            params->u.mem.start = memory_map[i].start;
            params->u.mem.size = memory_map[i].size;
            params = tag_next(params);
        }
    }
    可以看出,在 memory_map[]數(shù)組中,每一個(gè)有效的內(nèi)存段都對(duì)應(yīng)一個(gè) ATAG_MEM 參數(shù)標(biāo)記。

    Linux 內(nèi)核在啟動(dòng)時(shí)可以以命令行參數(shù)的形式來(lái)接收信息,利用這一點(diǎn)我們可以向內(nèi)核提供那些內(nèi)核不
    能自己檢測(cè)的硬件參數(shù)信息,或者重載(override)內(nèi)核自己檢測(cè)到的信息。
    比如,我們用這樣一個(gè)命令行參數(shù)字符串"console=ttyS0,115200n8"來(lái)通知內(nèi)核以ttyS0 作為控制臺(tái),且串口采用 "115200bps、無(wú)奇偶校驗(yàn)、8位數(shù)據(jù)位"這樣的設(shè)置。下面是一段設(shè)置調(diào)用內(nèi)核命令行參數(shù)字符串的示例代碼:
        char *p;
        /* eat leading white space */
        for(p = commandline; *p == ' '; p++)
        ;
        /* skip non-existent command lines so the kernel will still
        * use its default command line.
        */
        if(*p == '