移植 bootm 命令啓動內核

bootloader 的兩個作用:
1、初始化硬件; 2、啓動OS。

bootm命令就是用來啓動操作系統的。

內核文件分爲 zImage 和 uImage, uImage 是 zImage 的基礎上增加了信息頭,bootm 命令只能使用 uImage 文件。

bootm命令工作流程:
1、檢查信息頭(是否壓縮/os種類/幻數等信息)
2、根據os的類型調用相關函數
2.1、獲取內核地址
2.2、獲取CPU型號
2.3、設置啓動參數(內存大小、串口號)等
3、啓動 Linux 內核

在本次編寫的bootloader中省去了第一個步驟,沒有檢查信息頭。

內核本身有處理器參數,bootm命令中傳入的CPU參數需要與之相同。

代碼編寫:

boot.c

#include "atag.h"
#include "string.h"

#define SDRAM_KERNEL_START 0x31000000 //內核的下載的位置
#define SDRAM_TAGS_START   0x30000100
#define SDRAM_ADDR_START   0x30000000
#define SDRAM_TOTAL_SIZE   0x04000000

void (*theKernel)(int , int , unsigned int );

struct tag *pCurTag;

const char *cmdline = "console=ttySAC0,115200 init=/init";

void setup_core_tag()
{
     pCurTag = (struct tag *)SDRAM_TAGS_START;

     pCurTag->hdr.tag = ATAG_CORE;
     pCurTag->hdr.size = tag_size(tag_core); 

     pCurTag->u.core.flags = 0;
     pCurTag->u.core.pagesize = 4096;
     pCurTag->u.core.rootdev = 0;

     pCurTag = tag_next(pCurTag);
}

void setup_mem_tag()
{
     pCurTag->hdr.tag = ATAG_MEM;
     pCurTag->hdr.size = tag_size(tag_mem32); 

     pCurTag->u.mem.start = SDRAM_ADDR_START;
     pCurTag->u.mem.size = SDRAM_TOTAL_SIZE;

     pCurTag = tag_next(pCurTag);
}

void setup_cmdline_tag()
{
     int linelen = strlen(cmdline);

     pCurTag->hdr.tag = ATAG_CMDLINE;
     pCurTag->hdr.size = (sizeof(struct tag_header)+linelen+1+4)>>2;

     strcpy(pCurTag->u.cmdline.cmdline,cmdline);

     pCurTag = tag_next(pCurTag);
}

void setup_end_tag()
{
    pCurTag->hdr.tag = ATAG_NONE;
    pCurTag->hdr.size = 0;
}

void boot_linux()
{
    //1. 獲取Linux啓動地址
    theKernel = (void (*)(int , int , unsigned int ))SDRAM_KERNEL_START;

    //2. 設置啓動參數
    //2.1 設置核心啓動參數
    setup_core_tag();

    //2.2 設置內存參數
    setup_mem_tag();

    //2.3 設置命令行參數
    setup_cmdline_tag();

    //2.4 設置參數結束標誌
    setup_end_tag();

    //3. 啓動Linux系統
    theKernel(0,168,SDRAM_TAGS_START);//168是處理器編號,第三個是啓動地址
}

atag.h

//參數區的數據結構就是tag結構

#define ATAG_CORE      0x54410001
#define ATAG_MEM       0x54410002
#define ATAG_CMDLINE   0x54410009
#define ATAG_NONE      0x00000000

struct tag_header {
    unsigned int size;
    unsigned int tag;
};

struct tag_core {
    unsigned int flags;     
    unsigned int pagesize;
    unsigned int rootdev;
};

struct tag_mem32 {
    unsigned int    size;
    unsigned int    start;  
};

struct tag_cmdline {
    char    cmdline[1]; 
};

struct tag {
    struct tag_header hdr;
    union {
        struct tag_core     core;
        struct tag_mem32    mem;
        struct tag_cmdline  cmdline;
    } u;
};

#define tag_size(type)  ((sizeof(struct tag_header) + sizeof(struct type)) >> 2)
#define tag_next(t) ((struct tag *)((unsigned int *)(t) + (t)->hdr.size))
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章