bootm命令移植

bootloader的作用有两个,一是初始化软硬件,二是启动操作系统。bootm命令是从内存中运行某一程序,通常用该命令来启动操作系统。比如通过tftp下载内核到内存0x31000000处,可通过执行指令bootm 31000000启动内核。
ps:内核文件有两个:zImage和uImage,zImage是纯粹的内核程序,uImage则在zImage的基础上添加了信息头,一般来说bootm命令使用的是uImage。

bootm命令所完成的工作如下:

这里写图片描述

为了简单,这里省去了检查信息头这步骤,因此可采用zImage。
源文件为:

#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";/*这是Linux内核需要的命令行*/

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;
     /*将SDRAM_KERNEL_START强制转换为(void (*)(int , int , unsigned int ))类型指针,然后对函数指针进行赋值*/
    //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);/*调用函数,这是函数指针的用法*/

    /*内核接受三个参数,第一个为0,第二个为处理器编号,第三个为启动参数的地址*/
}

头文件为:

#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))

ps:启动Linux内核时,若内核启动一部分后停止,则问题很可能是写错了处理器编号。代码theKernel(0,168,SDRAM_TAGS_START)中的168为处理器S3C2440的编号。启动程序中的处理器编号会作为参数传递给内核,而内核中也存在着一个处理器编号序列,两者必须一样才能正常启动内核。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值